Reputation: 377
My goal is: I want to step into the some line of code of STL istream
. So I used custom built "LIBC++13" with "Debug" build type(the command I used are shown at the bottom), so that (I think) I can get a fully debuggable version of STL, and be able to step into everything I want. But I got a problem.
Here are my breakpoints settings for istream
, BREAKPOINT A(Line 1447)
and want to step into Line 310
:
// -*- C++ -*-
//===--------------------------- istream ----------------------------------===//
// ..................(other).....................
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Allocator>& __str)
{
ios_base::iostate __state = ios_base::goodbit;
typename basic_istream<_CharT, _Traits>::sentry __sen(__is); // BREAKPOINT A (Line 1447)
if (__sen) // Line 1448
{
// ...
}
// ..................(other).....................
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& __is,
bool __noskipws)
: __ok_(false)
{
if (__is.good()) // Want To Step Into Here (Line 310)
{
// ...
}
and the program:
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream ifs{"testdata.txt"};
string tmp{};
ifs >> tmp;
}
My problem is: With GDB, when I stopped at "BREAKPOINT A", I can step into "Line 310". But with LLDB, when I stopped at "BREAKPOINT A", I cannot step into "Line 310", and trying to step into would cause execution stopping at "Line 1448", which just skipping the "Line 310". Why was that? And Moreover, either with LLDB or GBD, I just cannot explicitly set breakpoint at "Line 310". Have no idea what happened in my situation.
LIBC++13 is built by command: (using the examples in Building Libcxx Guides, /usr/local/myllvm
is my install location))
cmake -G Ninja -S llvm -B build \
-DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \
-DCMAKE_BUILD_TYPE="Debug" \
-DCMAKE_INSTALL_PREFIX="/usr/local/myllvm" \
-DCMAKE_CXX_COMPILER="clang++"
Program is compiled with recommended options:
clang++ -nostdinc++ -nostdlib++ \
-isystem /usr/local/myllvm/include/c++/v1 \
-L /usr/local/myllvm/lib \
-Wl,-rpath,/usr/local/myllvm/lib \
-lc++ -g -O0 test1.cpp
Upvotes: 2
Views: 418
Reputation: 377
Thanks @Jim Ingham for the first address on my problems.
In addition to @Jim Ingham's Answer, which solved most of my problems, I'm going to add some supplementary information for resting part of my problems.
- Why either with LLDB or GBD, we just cannot explicitly set a breakpoint at "Line 310".
The short reason: we can directly set breakpoints at "Line 1447" is because this line resides in istream
header file(i.e., INSTALL_DIR/include/c++/v1/istream
), whereas "Line 310" does not and instead resides in original istream
source file(i.e., BUILD_DIR/include/c++/v1/istream
).
What actually happened is all related to the source information provided by debuggable executable object file, and despite appearances, those two lines which are supposed to be in a same source file, are seperated because of its generated DWARF sections contains different information for those two lines:
########### Using "llvm-dwarfdump" tool
########### Output by: llvm-dwarfdump a.out
...
# This relates to "Line 310"
0x00003a4a: DW_TAG_class_type
DW_AT_name ("sentry")
DW_AT_declaration (true)
...
# This relates to "Line 1448"
0x00004ae4: DW_TAG_variable
DW_AT_location (DW_OP_fbreg -24)
DW_AT_name ("__sen")
DW_AT_decl_file ("/usr/local/myllvm/include/c++/v1/istream")
DW_AT_decl_line (1448)
DW_AT_type (0x00003a4a "sentry")
...
According to DWARF 2 Standard, DW_AT_declaration (true)
meaning that corresponding class type is defined elsewhere, thus, we just cannot set that breakpoint UNLESS debugger has already step into the instructions relating to that class's definition. (TODO: Still no ideas about how debuggers find it dynamically)
Conversely, we can set the breakpoint at the line which needs the symbol __sen
, and reason why it works is because there is already fully debuggable information generated by compiler for it, that is, DW_AT_decl_file
corresponds to "Source File", DW_AT_decl_line
corresponds to "Source File Line Number", etc.
Upvotes: 0
Reputation: 27110
By default, lldb treats functions in the std:::
namespace the same way as functions without debug information, and auto-steps back out instead of stopping in the function.
For most users, the fact that you have source information for inlined stl functions is more an accident of the implementation than an indication of interest in those functions; and stepping into STL function bodies is disruptive and not helpful.
This behavior is controlled by the lldb setting target.process.thread.step-avoid-regex
- if lldb steps into a function that matches this regex, lldb will auto-step out again. The default value is:
(lldb) settings show target.process.thread.step-avoid-regexp
target.process.thread.step-avoid-regexp (regex) = ^std::
If you do need to step into STL functions, just run:
(lldb) settings clear target.process.thread.step-avoid-regexp
and then lldb will stop in stl functions for which you have source information.
Upvotes: 4