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

Method resolveLocalVariables

src/pystack/_pystack/pyframe.cpp:109–159  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

107}
108
109void
110FrameObject::resolveLocalVariables()
111{
112 LOG(DEBUG) << "Resolving local variables from frame number " << d_frame_no;
113 if (d_code == nullptr) {
114 LOG(INFO) << "Frame is a shim frame, skipping local variable resolution";
115 return;
116 }
117
118 const size_t n_arguments = d_code->NArguments();
119 const size_t n_locals = d_code->Varnames().size();
120 Structure<py_frame_v> frame(d_manager, d_addr);
121 const remote_addr_t locals_addr = frame.getFieldRemoteAddress(&py_frame_v::o_localsplus);
122
123 if (n_locals < n_arguments) {
124 throw std::runtime_error("Found more arguments than local variables");
125 }
126
127 std::vector<remote_addr_t> tuple_buffer(n_locals);
128 LOG(DEBUG) << "Copying buffer containing local variables";
129 d_manager->copyMemoryFromProcess(locals_addr, n_locals * sizeof(remote_addr_t), tuple_buffer.data());
130
131 auto addLocal = [&](size_t index, auto& map) {
132 remote_addr_t addr = tuple_buffer[index];
133 if (addr == (remote_addr_t) nullptr) {
134 return;
135 }
136
137 if (d_manager->versionIsAtLeast(3, 14)) {
138 // In Python 3.14, the local variable is a PyStackRef: a pointer
139 // with extra flags set in its low bits. Ignore the flags.
140 addr = addr & (~3);
141 }
142
143 std::string key = d_code->Varnames()[index];
144
145 LOG(DEBUG) << "Copying local variable at address " << std::hex << std::showbase << addr;
146 std::string value = Object(d_manager, addr).toString();
147 LOG(DEBUG) << "Local variable resolved to: " << key << ": " << value;
148 map.insert(std::make_pair(key, value));
149 };
150
151 LOG(DEBUG) << "Copying content of local variables";
152 for (size_t i = 0; i < tuple_buffer.size(); ++i) {
153 if (i < n_arguments) {
154 addLocal(i, d_arguments);
155 } else {
156 addLocal(i, d_locals);
157 }
158 }
159}
160
161ssize_t
162FrameObject::FrameNo() const

Callers

nothing calls this directly

Calls 8

LOGClass · 0.85
ObjectClass · 0.85
NArgumentsMethod · 0.80
sizeMethod · 0.80
getFieldRemoteAddressMethod · 0.80
versionIsAtLeastMethod · 0.80
toStringMethod · 0.80
copyMemoryFromProcessMethod · 0.45

Tested by

no test coverage detected