| 54 | } |
| 55 | |
| 56 | std::unique_ptr<CodeObject> |
| 57 | FrameObject::getCode( |
| 58 | const std::shared_ptr<const AbstractProcessManager>& manager, |
| 59 | Structure<py_frame_v>& frame) |
| 60 | { |
| 61 | remote_addr_t py_code_addr = frame.getField(&py_frame_v::o_code); |
| 62 | if (manager->versionIsAtLeast(3, 14)) { |
| 63 | py_code_addr = py_code_addr & (~3); |
| 64 | } |
| 65 | |
| 66 | LOG(DEBUG) << std::hex << std::showbase << "Attempting to construct code object from address " |
| 67 | << py_code_addr; |
| 68 | |
| 69 | uintptr_t last_instruction; |
| 70 | if (manager->versionIsAtLeast(3, 11)) { |
| 71 | last_instruction = frame.getField(&py_frame_v::o_prev_instr); |
| 72 | } else { |
| 73 | last_instruction = frame.getField(&py_frame_v::o_lasti); |
| 74 | } |
| 75 | int32_t tlbc_index = -1; |
| 76 | if (manager->versionIsAtLeast(3, 14) && manager->isFreeThreaded()) { |
| 77 | uintptr_t tlbc_index_addr = frame.getFieldRemoteAddress(&py_frame_v::o_prev_instr) |
| 78 | + sizeof(last_instruction) + sizeof(Python3_14::_PyStackRef); |
| 79 | manager->copyMemoryFromProcess(tlbc_index_addr, sizeof(tlbc_index), &tlbc_index); |
| 80 | } |
| 81 | try { |
| 82 | return std::make_unique<CodeObject>(manager, py_code_addr, last_instruction, tlbc_index); |
| 83 | } catch (const RemoteMemCopyError& ex) { |
| 84 | // This may not have been a code object at all, or it may have been |
| 85 | // trashed by memory corruption. Either way, indicate that we failed |
| 86 | // to understand what code this frame is running. |
| 87 | return std::make_unique<CodeObject>("???", "???", LocationInfo{0, 0, 0, 0}); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | bool |
| 92 | FrameObject::isEntry( |
nothing calls this directly
no test coverage detected