Skipping boring functions in debuggers
In debuggers, stepping 2024-12-30 07:47:8 Author: maskray.me(查看原文) 阅读量:6 收藏

In debuggers, stepping into a function with arguments that involve function calls may step into the nested function calls, even if they are simple and uninteresting, such as those found in the C++ STL.

GDB

Consider the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cstdio>
#include <memory>
#include <vector>
using namespace std;

void foo(int i, int j) {
printf("%d %d\n", i, j);
}

int main() {
auto i = make_unique<int>(3);
vector v{1,2};
foo(*i, v.back());
}

When GDB stops at the foo call, the step (s) command will step into std::vector::back and std::unique_ptr::operator*. While you can execute finish (fin) and execute s again, it's time-consuming and distracting, especially when dealing with complex argument expressions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
% g++ -g a.cc -o a
% gdb ./a
...
(gdb) s
std::vector<int, std::allocator<int> >::back (this=0x7fffffffddd0) at /usr/include/c++/14.2.1/bits/stl_vector.h:1235
1235 back() _GLIBCXX_NOEXCEPT
(gdb) fin
Run till exit from #0 std::vector<int, std::allocator<int> >::back (this=0x7fffffffddd0) at /usr/include/c++/14.2.1/bits/stl_vector.h:1235
0x00005555555566f8 in main () at a.cc:13
13 foo(*i, v.back());
Value returned is $1 = (__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type &) @0x55555556c2d4: 2
(gdb) s
std::unique_ptr<int, std::default_delete<int> >::operator* (this=0x7fffffffddc0) at /usr/include/c++/14.2.1/bits/unique_ptr.h:447
447 __glibcxx_assert(get() != pointer());
(gdb) fin
Run till exit from #0 std::unique_ptr<int, std::default_delete<int> >::operator* (this=0x7fffffffddc0) at /usr/include/c++/14.2.1/bits/unique_ptr.h:447
0x0000555555556706 in main () at a.cc:13
13 foo(*i, v.back());
Value returned is $2 = (int &) @0x55555556c2b0: 3
(gdb) s
foo (i=3, j=2) at a.cc:7
7 printf("%d %d\n", i, j);

Fortunately, GDB provides the skip command to skip functions that match a regex or filenames that match a glob (GDB 7.12 feature). You can skip all demangled function names that start with std::.

1
skip -rfu ^std::

Alternatively, you can execute skip -gfi /usr/include/c++/*/bits/* to skip these libstdc++ files.

Important note:

The skip command's file matching behavior uses the fnmatch function with the FNM_FILE_NAME flag. This means the wildcard character (*) won't match slashes. So, skip -gfi /usr/* won't exclude /usr/include/c++/14.2.1/bits/stl_vector.h.

I proposed to drop the FNM_FILE_NAME flag. If this is accepted, I will be able to skip a project directory with

1
skip -gfi */include/llvm/ADT/*

instead of

1
skip -gfi /home/ray/llvm/llvm/include/llvm/ADT/*

User functions called by skipped functions

When a function (let's call it "A") is skipped during debugging, any user-defined functions that are called by "A" will also be skipped.

For example, consider the following code snippet:

1
2
3
std::vector<int> a{1, 2};
if (std::all_of(a.begin(), a.end(), predicate)) {
}

If std::all_of is skipped due to a skip command, predicate called within std::all_of will also be skipped when you execute s at the if statement.

LLDB

By default, LLDB avoids stepping into functions whose names start with std:: when you use the s (step, thread step-in) command. This behavior is controlled by a setting:

1
2
(lldb) settings show target.process.thread.step-avoid-regexp
target.process.thread.step-avoid-regexp (regex) = ^std::

Visual Studio

Visual Studio provides a debugging feature Just My Code that automatically steps over calls to system, framework, and other non-user code.

It also supports a Step Into Specific command, which seems interesting.

The implementation inserts a call to __CheckForDebuggerJustMyCode at the start of every user function. David Spickett has a description at this LLDB feature request: https://github.com/llvm/llvm-project/issues/61152.

1
2
3
std::vector<int> a{1, 2};
if (std::all_of(a.begin(), a.end(), test)) {
}

文章来源: https://maskray.me/blog/2024-12-30-skipping-boring-functions-in-debuggers
如有侵权请联系:admin#unsafe.sh