MCPcopy Create free account
hub / github.com/bloomberg/pystack / getLocationInfo

Function getLocationInfo

src/pystack/_pystack/pycode.cpp:104–189  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

102}
103
104static LocationInfo
105getLocationInfo(
106 const std::shared_ptr<const AbstractProcessManager>& manager,
107 remote_addr_t code_addr,
108 Structure<py_code_v>& code,
109 uintptr_t last_instruction_index,
110 int tlbc_index)
111{
112 int code_lineno = code.getField(&py_code_v::o_firstlineno);
113 remote_addr_t lnotab_addr = code.getField(&py_code_v::o_lnotab);
114 LOG(DEBUG) << std::hex << std::showbase << "Copying lnotab data from address " << lnotab_addr;
115 std::string lnotab = manager->getBytesFromAddress(lnotab_addr);
116
117 assert(manager->versionIsAtLeast(3, 11) || lnotab.size() % 2 == 0);
118 std::string::size_type last_executed_instruction = last_instruction_index;
119
120 LocationInfo location_info = LocationInfo{0, 0, 0, 0};
121
122 // Check out https://github.com/python/cpython/blob/main/Objects/lnotab_notes.txt for the format of
123 // the lnotab table in different versions of the interpreter.
124 if (manager->versionIsAtLeast(3, 14) && manager->isFreeThreaded()) {
125 uintptr_t code_adaptive = code.getFieldRemoteAddress(&py_code_v::o_code_adaptive);
126 uintptr_t tlbc_entries_addr = code_adaptive - sizeof(void*);
127 uintptr_t tlbc_entries;
128 manager->copyMemoryFromProcess(tlbc_entries_addr, sizeof(tlbc_entries), &tlbc_entries);
129 Py_ssize_t tlbc_size;
130 manager->copyMemoryFromProcess(tlbc_entries, sizeof(tlbc_size), &tlbc_size);
131 std::vector<uintptr_t> vec(tlbc_size);
132 manager->copyMemoryFromProcess(
133 tlbc_entries + sizeof(tlbc_size),
134 tlbc_size * sizeof(uintptr_t),
135 vec.data());
136 LOG(DEBUG) << "tlbc_index=" << tlbc_index << " tlbc_size=" << tlbc_size;
137 uintptr_t code_adaptive_actual = vec[tlbc_index];
138 ptrdiff_t addrq =
139 (reinterpret_cast<uint16_t*>(last_instruction_index)
140 - reinterpret_cast<uint16_t*>(code_adaptive_actual));
141 LocationInfo posinfo;
142 bool ret = parse_linetable(addrq, lnotab, code_lineno, &posinfo);
143 if (ret) {
144 location_info.lineno = posinfo.lineno;
145 location_info.end_lineno = posinfo.end_lineno;
146 location_info.column = posinfo.column;
147 location_info.end_column = posinfo.end_column;
148 }
149 } else if (manager->versionIsAtLeast(3, 11)) {
150 uintptr_t code_adaptive = code.getFieldRemoteAddress(&py_code_v::o_code_adaptive);
151 ptrdiff_t addrq =
152 (reinterpret_cast<uint16_t*>(last_instruction_index)
153 - reinterpret_cast<uint16_t*>(code_adaptive));
154 LocationInfo posinfo;
155 bool ret = parse_linetable(addrq, lnotab, code_lineno, &posinfo);
156 if (ret) {
157 location_info.lineno = posinfo.lineno;
158 location_info.end_lineno = posinfo.end_lineno;
159 location_info.column = posinfo.column;
160 location_info.end_column = posinfo.end_column;
161 }

Callers 1

CodeObjectMethod · 0.85

Calls 8

LOGClass · 0.85
parse_linetableFunction · 0.85
getBytesFromAddressMethod · 0.80
versionIsAtLeastMethod · 0.80
sizeMethod · 0.80
isFreeThreadedMethod · 0.80
getFieldRemoteAddressMethod · 0.80
copyMemoryFromProcessMethod · 0.45

Tested by

no test coverage detected