debugging 如何让LLDB进入std::cout的operator< < ?

iih3973s  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(88)

我使用的是ArchLinux,安装了调试信息(将存储库URL添加到/etc/pacman.conf和paru -S glibc-debug gcc-debug)。
我创建了一个名为hello.cpp的文件。

#include <iostream>

int main() {
    std::cout << "こんにちは" << std::endl;
}

字符串
在运行clang++ -g hello.cpp之后,我用gdblldb调试了a.out,这让我发现只有LLDB无法单步执行std::cout的操作符<<。
我执行了gdb和一些内部命令。

> gdb a.out
(gdb) b main
(gdb) r
(gdb) s


输出结果是这样的。可以看到GDB可以在<<操作符内部进行跟踪。

❯ gdb a.out
GNU gdb (GDB) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb) b main
Breakpoint 1 at 0x114d: file hello.cpp, line 4.
(gdb) r
Starting program: /***/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Breakpoint 1, main () at hello.cpp:4
4           std::cout << "こんにちは" << std::endl;
(gdb) s
std::operator<< <std::char_traits<char> > (__out=..., __s=0x555555556004 "こんにちは") at /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/ostream:662
662         operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
(gdb)


另一方面,当我尝试用LLDB做同样的事情时,

> lldb a.out
(lldb) b main
(lldb) r
(lldb) s


X1 M7 N1 X的行被完全跳过。

❯ lldb a.out
(lldb) target create "a.out"
Current executable set to '/***/a.out' (x86_64).
(lldb) b main
Breakpoint 1: where = a.out`main + 4 at hello.cpp:4:18, address = 0x000000000000114d
(lldb) r
Process 347983 launched: '/***/a.out' (x86_64)
Process 347983 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x000055555555514d a.out`main at hello.cpp:4:18
   1    #include <iostream>
   2   
   3    int main() {
-> 4        std::cout << "こんにちは" << std::endl;
   5    }
(lldb) s
こんにちはProcess 347983 stopped
* thread #1, name = 'a.out', stop reason = step in
    frame #0: 0x0000555555555178 a.out`main at hello.cpp:5:1
   2   
   3    int main() {
   4        std::cout << "こんにちは" << std::endl;
-> 5    }
(lldb)


我认为LLDB最初应该能够调试标准库中的函数。
这是正确的行为吗?有没有办法用LLDB进入std::cout的operator<<?

输出

❯ /usr/bin/g++ -g -v hello.cpp
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,objc,obj-c++ --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.1.1 20230429 (GCC) 
COLLECT_GCC_OPTIONS='-g' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'a-'
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/cc1plus -quiet -v -D_GNU_SOURCE hello.cpp -quiet -dumpdir a- -dumpbase hello.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -version -o /tmp/cc0gSOV9.s
GNU C++17 (GCC) version 13.1.1 20230429 (x86_64-pc-linux-gnu)
        compiled by GNU C version 13.1.1 20230429, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.26-GMP

warning: MPFR header version 4.2.0 differs from library version 4.2.0-p9.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../include/c++/13.1.1
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../include/c++/13.1.1/x86_64-pc-linux-gnu
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../include/c++/13.1.1/backward
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/include-fixed
 /usr/include
End of search list.
Compiler executable checksum: e149eaca55f4ee2a0171ba2b54b0dc8d
COLLECT_GCC_OPTIONS='-g' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'a-'
 as -v --gdwarf-5 --64 -o /tmp/cc5MF67V.o /tmp/cc0gSOV9.s
GNU assembler version 2.40.0 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.40.0
COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-g' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'a.'
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/cctNfJ8Z.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../.. /tmp/cc5MF67V.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib/crtn.o
COLLECT_GCC_OPTIONS='-g' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'a.'

❯ /usr/bin/gdb --version
GNU gdb (GDB) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

❯ /usr/bin/lldb --version
lldb version 15.0.7

❯ ldd a.out
        linux-vdso.so.1 (0x00007ffcfaff6000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f0751800000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f0751a98000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f07517db000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f07515f1000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f0751bc6000)

❯ nm -C a.out
0000000000003da8 d _DYNAMIC
0000000000003fe8 d _GLOBAL_OFFSET_TABLE_
0000000000002000 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@GLIBCXX_3.4
0000000000002014 r std::__detail::__integer_to_chars_is_unsigned<unsigned int>
0000000000002015 r std::__detail::__integer_to_chars_is_unsigned<unsigned long>
0000000000002016 r std::__detail::__integer_to_chars_is_unsigned<unsigned long long>
0000000000004040 B std::cout@GLIBCXX_3.4
                 U std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)@GLIBCXX_3.4
                 U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@GLIBCXX_3.4
0000000000002018 r __GNU_EH_FRAME_HDR
0000000000004020 D __TMC_END__
0000000000004020 B __bss_start
                 w __cxa_finalize@GLIBC_2.2.5
0000000000004010 D __data_start
0000000000004018 D __dso_handle
                 w __gmon_start__
                 U __libc_start_main@GLIBC_2.34
0000000000004020 D _edata
0000000000004158 B _end
0000000000001180 T _fini
0000000000001000 T _init
0000000000001050 T _start
0000000000004010 W data_start
0000000000001149 T main

jhkqcmku

jhkqcmku1#

谢谢你的评论。@Jim Ingham已经在https://stackoverflow.com/a/70560542/22234700中提供了解决方案。
答案解释说,该行为是LLDB的默认值,可以通过设置target.process.thread.step-avoid-regexp来控制。

相关问题