[Lldb-commits] [lldb] LLDB Debuginfod tests and a fix or two (PR #90622)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Wed May 8 06:19:27 PDT 2024


================
@@ -87,8 +105,15 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
   FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
   FileSpec dsym_fspec =
       PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
-  if (!dsym_fspec)
-    return nullptr;
+  if (!dsym_fspec || IsDwpSymbolFile(module_sp, dsym_fspec)) {
+    // If we have a stripped binary or if we got a DWP file, we should prefer
+    // symbols in the executable acquired through a plugin.
+    ModuleSpec unstripped_spec =
+        PluginManager::LocateExecutableObjectFile(module_spec);
+    if (!unstripped_spec)
+      return nullptr;
+    dsym_fspec = unstripped_spec.GetFileSpec();
+  }
----------------
DavidSpickett wrote:

This is what I've figured out so far. It's like the previous issue I mentioned, except it's related to the program file, not `ld.so`.

If we look at the memory regions before this PR we see:
```
[0x00000000f7fe2000-0x00000000f7fe9000) ---
[0x00000000f7fe9000-0x00000000f7fea000) rw-
[0x00000000f7fea000-0x00000000f7feb000) r-- objc_imageinfo
[0x00000000f7feb000-0x00000000f7fec000) r-x .text
```

After we just have:
```
[0x00000000f7fe2000-0x00000000f7fec000) ---
```

Which means we have lost, or never loaded, the section information for this program file. Which makes sense given that it's compiled without debug information. We'll ask a plugin for the debug info and none of those will have it, so we exit early.

Problem is, Arm has 2 execution modes. Arm and Thumb. To know how to break properly in different code we look at markers on the sections. These set the `AddressClass` of the address value in LLDB to the right value.

In this case, we need to call `mmap`. This is in a Thumb section in `ld.so`, and we have it's section information. We don't need to break here though, only set the control register (cpsr) bit to indicate we want to run in Thumb mode, then write the PC to point to this location.

For the end of `mmap`, we need to return somewhere. So lldb says, why not `_start`, it's something we can count on existing on Linux. So LLDB needs to set the link register to that address, then place a breakpoint on the address to catch the program just as `mmap` finishes.

Problem is, after this PR we don't have section information to tell us that this area is Thumb. This means that `Platform::GetSoftwareBreakpointTrapOpcode` chooses an Arm breakpoint code. Now I don't know exactly what goes wrong there, I think in Thumb mode the program sees this encoding as some kind of backwards branch, and it ends up basically in the zero page and segfaults from there. This is why the call to `mmap` fails and we fall back to the interpreter.

So ideally we want to split the two concepts of 1. Section information and 2. Symbol file. So that we can load both without resetting the other. I'm going to look into that next.

And for some context, I think Arm is the only platform this section information is crucial. Potentially MIPS but also we dropped Linux MIPS support, and I don't know if those platforms mixed modes ever. So it's not surprising you didn't see this testing on more modern platforms.

https://github.com/llvm/llvm-project/pull/90622


More information about the lldb-commits mailing list