Step into in a function call from a shared library steps to the plt record, not to the corresponding code
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
I tried to debug the following C++ code:
```c++
1675 std::vector x = {1, 2, 3};
-> 1676 std::sort(x.begin(), x.end());
```
compiled with `g++ 11.4.0-2ubuntu1~20.04` and linked against `libstdc++` into a shared library (`.so` file).
LLDB version:
```
(lldb) version
lldb version 21.1.5 (https://github.com/llvm/llvm-project.git revision 8e2cd28cd4ba46613a46467b0c91b1cabead26cd)
clang revision 8e2cd28cd4ba46613a46467b0c91b1cabead26cd
llvm revision 8e2cd28cd4ba46613a46467b0c91b1cabead26cd
```
The `target.process.thread.step-avoid-regexp` option is totally disabled:
```
(lldb) settings show target.process.thread.step-avoid-regexp
target.process.thread.step-avoid-regexp (regex) = ""
```
I'm trying to get into the `std::sort` function, the `s` command doesn't work due to the absence of the debug information for the standard library. I'm trying to step info with force and get to the corresponding `plt` (`.plt.got`, actually):
```
(lldb) s -a false
Process 3327735 stopped
* thread #7, name = 'JIT Thread', stop reason = step in
frame #0: 0x00007ffff46f3890 libarkcompiler.so`___lldb_unnamed_symbol_a1d900 + 200592
libarkcompiler.so`___lldb_unnamed_symbol_a1d900:
-> 0x7ffff46f3890 <+200592>: endbr64
0x7ffff46f3894 <+200596>: jmpq *0xf68f2e(%rip) ; _GLOBAL_OFFSET_TABLE_ + 100320
0x7ffff46f389a <+200602>: nopw (%rax,%rax)
0x7ffff46f38a0 <+200608>: endbr64
```
I get into the deserved sources only after pressing `s` two times more:
```
* thread #7, name = 'JIT Thread', stop reason = instruction step into
frame #0: 0x00007ffff699a3f2 libarkruntime.so`std::vector>::end(this=size=0) at stl_vector.h:829:7
826 * element order.
827 */
828 iterator
-> 829 end() _GLIBCXX_NOEXCEPT
830 { return iterator(this->_M_impl._M_finish); }
831
```
What I see, when I'm trying to find all the available `std::vector>::end()` symbols in my images:
```
(lldb) im look -r -s "std::vector>::end\(\)$"
1 symbols match the regular expression 'std::vector>::end\(\)$' in .../out/dbg-llvm/lib/libarkbase.so:
Address: libarkbase.so[0x0000000000071f54] (libarkbase.so.PT_LOAD[1]..text + 337396)
Summary: libarkbase.so`std::vector>::end() at stl_vector.h:829:7
2 symbols match the regular expression 'std::vector>::end\(\)$' in .../out/dbg-llvm/lib/libarkcompiler.so:
Address: libarkcompiler.so[0x0000000000b302c4] (libarkcompiler.so.PT_LOAD[1]..text + 473828)
Summary: libarkcompiler.so`std::vector>::end() at stl_vector.h:829:7
Address: libarkcompiler.so[0x00000000009aefc0] (libarkcompiler.so.PT_LOAD[1]..plt + 200608)
Summary: libarkcompiler.so`symbol stub for: std::vector>::end()
2 symbols match the regular expression 'std::vector>::end\(\)$' in .../out/dbg-llvm/lib/libarkruntime.so:
Address: libarkruntime.so[0x00000000012de3f2] (libarkruntime.so.PT_LOAD[1]..text + 863346)
Summary: libarkruntime.so`std::vector>::end() at stl_vector.h:829:7
Address: libarkruntime.so[0x000000000112ecf0] (libarkruntime.so.PT_LOAD[1]..plt + 195792)
Summary: libarkruntime.so`symbol stub for: std::vector>::end()
```
I believe, the deserved symbol is:
```
2 symbols match the regular expression 'std::vector>::end\(\)$' in .../out/dbg-llvm/lib/libarkcompiler.so:
...
Address: libarkcompiler.so[0x00000000009aefc0] (libarkcompiler.so.PT_LOAD[1]..plt + 200608)
Summary: libarkcompiler.so`symbol stub for: std::vector>::end()
```
instead of the corresponding record in `.text`.
What confused me a bit and may be related to the root cause. In the output of `(lldb) im look -r -s "std::vector>::end\(\)$"` I see `libarkcompiler.so.PT_LOAD[1]..plt + 200608` what looks as true:
`200608` is `0x30fa0`, `0x000000000112ecf0 - 0x30fa0 = 97ea020`, this the start of the `.plt` section in the elf file `libarkcompiler.so`:
```
$ readelf -S lib/libarkcompiler.so
[Nr] Name Type Address Offset Size EntSize Flags Link Info Align
[11] .plt PROGBITS 000000000097e020 0097e020 000000000009eef0 0000000000000010 AX 0 0 16
[12] .plt.got PROGBITS 0000000000a1cf10 00a1cf10 00000000000009f0 0000000000000010 AX 0 0 16
```
But in the debug session, once I've done `s -a false`, I got the following:
```
(lldb) s -a false
Process 3360935 stopped
* thread #7, name = 'JIT Thread', stop reason = step in
frame #0: 0x00007ffff46f3890 libarkcompiler.so`___lldb_unnamed_symbol_a1d900 + 200592
libarkcompiler.so`___lldb_unnamed_symbol_a1d900:
-> 0x7ffff46f3890 <+200592>: endbr64
```
`200592 (0x30f90)` is the offset to `$rip (0x7ffff46f3890)`, the pc at the start of the corresponding PLT record, from the start of the **loaded** `.plt.got` section:
```
(lldb) im dump sections libarkcompiler.so
0x00000006 libarkcompiler.so.PT_LOAD[1]..plt
0x000000000000000c code [0x00007ffff46c1f10-0x00007ffff46c2900)
7ffff46f3890
0x00000006 libarkcompiler.so.PT_LOAD[1]..plt.got
0x000000000000000d code [0x00007ffff46c2900-0x00007ffff47617e0)
7ffff46f3890
yep, 30f90 or 200592
0x00000006 libarkcompiler.so.PT_LOAD[1]..plt.sec
0x000000000000000e code [0x00007ffff47617e0-0x00007ffff51116b8) r-x 0x00abc7e0 0x009afed8
```
Actually, `___lldb_unnamed_symbol_a1d900` is the start of the **loaded** `plt.got` section while `a1d900` is the file address of the start of the `.plt.sec`:
```
$ readelf -S lib/libarkcompiler.so | grep 1d900
[13] .plt.sec PROGBITS 0000000000a1d900 00a1d900
```
How it looks in the debugger:
```
(lldb) disassemble -c 30
libarkcompiler.so`___lldb_unnamed_symbol_a1d900:
0x7ffff46c2900 <+0>: endbr64
0x7ffff46c2904 <+4>: jmpq *0xf816f6(%rip) ; _GLOBAL_OFFSET_TABLE_ + 24
0x7ffff46c290a <+10>: nopw (%rax,%rax)
...
```
Contributor guide
Research direction
Reproduce the stepping behavior with the shared-library C++ example, using `s -a false`, `target.process.thread.step-avoid-regexp`, `image lookup`, and section disassembly. Compare the PLT or `.plt.got` stop with the resolved `std::vector::end()` code and determine whether stepping should reach the corresponding `.text` symbol instead; done when the behavior is explained and covered by an appropriate LLDB regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100