auto start = read<uintptr_t>(chunk);
auto length = read<uintptr_t>(chunk);
- if (start == 0) {
+ if (start == 0 && length == 0) {
break;
}
return locationInfo.hasFileAndLine;
}
-bool Dwarf::findAddress(uintptr_t address, LocationInfo& locationInfo) const {
+bool Dwarf::findAddress(uintptr_t address,
+ LocationInfo& locationInfo,
+ LocationInfoMode mode) const {
locationInfo = LocationInfo();
- if (!elf_) { // no file
+ if (mode == LocationInfoMode::DISABLED) {
+ return false;
+ }
+
+ if (!elf_) { // No file.
return false;
}
// Fast path: find the right .debug_info entry by looking up the
// address in .debug_aranges.
uint64_t offset = 0;
- if (!findDebugInfoOffset(address, aranges_, offset)) {
- // NOTE: clang doesn't generate entries in .debug_aranges for
- // some functions, but always generates .debug_info entries.
- // We could read them from .debug_info but that's too slow.
- // If .debug_aranges is present fast address lookup is assumed.
+ if (findDebugInfoOffset(address, aranges_, offset)) {
+ // Read compilation unit header from .debug_info
+ folly::StringPiece infoEntry(info_);
+ infoEntry.advance(offset);
+ findLocation(address, infoEntry, locationInfo);
+ return locationInfo.hasFileAndLine;
+ } else if (mode == LocationInfoMode::FAST) {
+ // NOTE: Clang (when using -gdwarf-aranges) doesn't generate entries
+ // in .debug_aranges for some functions, but always generates
+ // .debug_info entries. Scanning .debug_info is slow, so fall back to
+ // it only if such behavior is requested via LocationInfoMode.
return false;
+ } else {
+ DCHECK(mode == LocationInfoMode::FULL);
+ // Fall back to the linear scan.
}
- // Read compilation unit header from .debug_info
- folly::StringPiece infoEntry(info_);
- infoEntry.advance(offset);
- findLocation(address, infoEntry, locationInfo);
- return true;
}
+
// Slow path (linear scan): Iterate over all .debug_info entries
// and look for the address in each compilation unit.
folly::StringPiece infoEntry(info_);