bad path, performance is not a concern.
| 98 | |
| 99 | // bad path, performance is not a concern. |
| 100 | std::string GetFormattedStack(std::shared_ptr<Frame> frame) const override { |
| 101 | if (frame == nullptr) { return " <unknown>\n"; } |
| 102 | std::string buffer; |
| 103 | const auto* py_frame = dynamic_cast<const PyFrame*>(frame.get()); |
| 104 | py::gil_scoped_acquire acquire; |
| 105 | while (py_frame != nullptr) { |
| 106 | const auto& lineno = py_frame->lineno; |
| 107 | const std::string line_text = [&]() -> std::string { |
| 108 | std::string line_text; |
| 109 | std::ifstream ifs(PyUnicodeToStdString(py_frame->filename)); |
| 110 | if (!ifs.is_open()) { return "<unknown>"; } |
| 111 | for (int j = 0; j < lineno; ++j) { std::getline(ifs, line_text); } |
| 112 | line_text.erase(line_text.find_last_not_of(' ') + 1); // suffixing spaces |
| 113 | line_text.erase(0, line_text.find_first_not_of(' ')); // prefixing spaces |
| 114 | return line_text; |
| 115 | }(); |
| 116 | // immitate python's stack trace format |
| 117 | fmt::format_to(std::back_inserter(buffer), " File \"{}\", line {}, in {}\n {}\n", |
| 118 | PyUnicodeToStdString(py_frame->filename), lineno, |
| 119 | PyUnicodeToStdString(py_frame->funcname), line_text); |
| 120 | py_frame = py_frame->back.get(); |
| 121 | } |
| 122 | return buffer; |
| 123 | }; |
| 124 | |
| 125 | #if PY_VERSION_HEX >= 0x03090000 |
| 126 | PyObject* RecordAndEvalFrame(PyThreadState* tstate, PyFrameObject* frame, |
nothing calls this directly
no test coverage detected