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

Method gatherInlineFrames

src/pystack/_pystack/unwinder.cpp:195–273  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

193}
194
195AbstractUnwinder::StatusCode
196AbstractUnwinder::gatherInlineFrames(
197 std::vector<NativeFrame>& native_frames,
198 const std::string& noninline_symname,
199 Dwarf_Addr pc,
200 Dwarf_Addr pc_corrected,
201 Dwarf_Die* cudie,
202 const char* mod_name) const
203{
204 // Gather initial source information . The inline functions are chained in a
205 // way that the symbol corresponding for a given scope represent the call that
206 // is happening at that scope, which means that for retrieving the file name
207 // and the source, we need to look at the previous scope, which is where the
208 // call happened. The initial source information can be obtained from the
209 // compilation unit itself.
210
211 LOG(DEBUG) << std::hex << std::showbase << "Gathering inline frames for frame @ " << pc;
212
213 auto srcloc = dwarf_getsrc_die(cudie, pc_corrected);
214 if (!srcloc) {
215 LOG(DEBUG) << std::hex << std::showbase << "Could not find main source information for PC @ "
216 << pc;
217 LOG(DEBUG) << "Found non-inline call without source information: " << noninline_symname;
218 native_frames.push_back({pc, demangleSymbol(noninline_symname), "???", 0, 0, mod_name});
219 return StatusCode::ERROR;
220 }
221
222 const char* filename = nullptr;
223 filename = dwarf_linesrc(srcloc, nullptr, nullptr);
224 if (filename == nullptr) {
225 filename = "???";
226 }
227 int line = 0;
228 int col = 0;
229 dwarf_lineno(srcloc, &line);
230 dwarf_linecol(srcloc, &col);
231
232 // Gather scope information for the given compilation unit
233 const ScopesInfo cudie_scopes_info = dwarfGetScopes(cudie, pc_corrected);
234 int ncudie_scopes = cudie_scopes_info.first;
235 if (ncudie_scopes == 0) {
236 LOG(DEBUG) << std::hex << std::showbase << "No inline scopes found for PC @ " << pc;
237 } else {
238 const Scopes& cudie_scopes = cudie_scopes_info.second;
239 const ScopesInfo scopes_info = dwarfGetScopesDie(cudie_scopes.get());
240 int nscopes = scopes_info.first;
241 const Scopes& scopes = scopes_info.second;
242
243 // Resolve all the inline frames in the obtained scopes
244
245 for (int i = 0; i < nscopes; ++i) {
246 Dwarf_Die* scope = &scopes.get()[i];
247 if (dwarf_tag(scope) != DW_TAG_inlined_subroutine) {
248 continue;
249 }
250 const std::optional<std::string> inlined_symname = DIENameFromScope(scope);
251 if (!inlined_symname) {
252 LOG(DEBUG) << "Scope with invalid name found @: " << scope->addr;

Callers

nothing calls this directly

Calls 3

LOGClass · 0.85
DIENameFromScopeFunction · 0.85
gatherInformationFromDIEFunction · 0.85

Tested by

no test coverage detected