English 中文(简体)
LLDB: 在 std: 共享_ ptr < T> 毁灭器上设置断点
原标题:LLDB: Set breakpoint on std::shared_ptr<T> destructor

如何在毁灭器 lldb 上设置一个符号断点?


<强力 > 引文: 我们想突破那里,检查一个演示程序中一个天真执行的前方链接列表的堆积溢出,其中丢弃含有10万元元素的清单会溢出,因为每个节点的毁灭器触发了该列表的 < code>- & gt; ext 毁灭器。

Sample file

#include <memory>

class Test {
public:
    Test() : a(1) { }
    
    int a;
};

int main() {
    auto sptr = std::make_shared<Test>();
    return 0;
}

尝试中断点( 最后一个断点由自动补全表示) :

(lldb) br set --name std::__1::shared_ptr<Test>::~shared_ptr
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) br set --name std::__1::shared_ptr<Test>::~shared_ptr[abi:v160006]()
WARNING:  Unable to resolve breakpoint to any actual locations.
问题回答

这样做有几种办法。

Test with two instantiations

First, just to make the test a little more interesting by having more than one instantiation of shared_ptr, I changed the sample to:

#include <iostream>
#include <memory>

struct Test {
    ~Test() { std::cout << "in ~Test
"; }
};

struct Test2 {
    ~Test2() { std::cout << "in ~Test2
"; }
};

int main() {
    auto sptr = std::make_shared<Test>();
    auto sptr2 = std::make_shared<Test2>();
    return 0;
}

然后,我编译并开始调试器使用:

$ clang++ -o prog -g -Wall prog.cc
$ lldb ./prog

1. Use breakpoint set --name

The breakpoint set --name command sets a breakpoint on all functions with a given name:

(lldb) breakpoint set --name ~shared_ptr
Breakpoint 1: 2 locations.
(lldb) breakpoint list
Current breakpoints:
1: name =  ~shared_ptr , locations = 2
  1.1: where = prog`std::shared_ptr<Test2>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001440], unresolved, hit count = 0 
  1.2: where = prog`std::shared_ptr<Test>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001460], unresolved, hit count = 0 

It also works with a more complete name, but the __1 stuff should not be there:

(lldb) br set --name std::__1::shared_ptr<Test>::~shared_ptr
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) br set --name std::shared_ptr<Test>::~shared_ptr
Breakpoint 2: where = prog`std::shared_ptr<Test>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = 0x0000000000001460

注:br bref="https://lldb.llvm.org/use/map.html"的别名(通过 unique prefix 机制)的别名,用于 brebpoint

2. Use breakpoint set --method

The breakpoint set --method <name> command sets a breakpoint on all methods with the given name:

(lldb) breakpoint set --method ~shared_ptr
Breakpoint 1: 2 locations.
(lldb) breakpoint list
Current breakpoints:
1: name =  ~shared_ptr , locations = 2
  1.1: where = prog`std::shared_ptr<Test2>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001440], unresolved, hit count = 0 
  1.2: where = prog`std::shared_ptr<Test>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001460], unresolved, hit count = 0 

3. Use breakpoint set --func-regex

The breakpoint set --func-regex <regex> command sets a breakpoint on all functions whose name matches the regex:

(lldb) breakpoint set --func-regex "^std::shared_ptr<.*>::~shared_ptr()$"
Breakpoint 1: 2 locations.
(lldb) breakpoint list
Current breakpoints:
1: regex =  ^std::shared_ptr<.*>::~shared_ptr()$ , locations = 2
  1.1: where = prog`std::shared_ptr<Test>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001460], unresolved, hit count = 0 
  1.2: where = prog`std::shared_ptr<Test2>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001440], unresolved, hit count = 0 

使用起来比较麻烦,但更精确。

4. Break at the line in the header

With b <file>:<line>, you can put breakpoints into all instantiations of a method at that location:

(lldb) b shared_ptr.h:103
warning: (x86_64) /home/scott/wrk/learn/lldb/break-in-shared-ptr-dtor/prog 0x000034a5: DW_AT_specification(0x000000000000088e) has no decl

warning: (x86_64) /home/scott/wrk/learn/lldb/break-in-shared-ptr-dtor/prog 0x000034c6: DW_AT_specification(0x0000000000000110) has no decl

Breakpoint 1: 2 locations.
(lldb) breakpoint list
Current breakpoints:
1: file =  shared_ptr.h , line = 103, exact_match = 0, locations = 2
  1.1: where = prog`std::shared_ptr<Test2>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001440], unresolved, hit count = 0 
  1.2: where = prog`std::shared_ptr<Test>::~shared_ptr() + 16 at shared_ptr.h:103:11, address = prog[0x0000000000001460], unresolved, hit count = 0 

This is reasonably easy and precise if you know where the method is implemented. I don t know why it spews those "has no decl" warnings, but it s not unusual for LLDB to do that sort of thing.

注: b breakpoint 是不同的命令!

5. Break in a callee

With any of these methods, you can instead put a breakpoint in one of the destructors defined in your own code:

(lldb) breakpoint set --method ~Test
Breakpoint 1: where = prog`Test::~Test() + 12 at prog.cc:5:25, address = 0x0000000000001e2c
(lldb) run
Process 588466 launched:  /home/scott/wrk/learn/lldb/break-in-shared-ptr-dtor/prog  (x86_64)
in ~Test2
Process 588466 stopped
* thread #1, name =  prog , stop reason = breakpoint 1.1
    frame #0: 0x0000555555555e2c prog`Test::~Test(this=0x000055555556cec0) at prog.cc:5:25
   2    #include <memory>
   3   
   4    struct Test {
-> 5        ~Test() { std::cout << "in ~Test
"; }
   6    };
   7   
   8    struct Test2 {
(lldb)  symbol table for <Unknown>.....K       [weird msg, I hit Ctrl-C]
error: No auto repeat.
(lldb) bt
* thread #1, name =  prog , stop reason = breakpoint 1.1
  * frame #0: 0x0000555555555e2c prog`Test::~Test(this=0x000055555556cec0) at prog.cc:5:25
    frame #1: 0x0000555555555e19 prog`void __gnu_cxx::new_allocator<Test>::destroy<Test>(this=0x000055555556cec0, __p=0x000055555556cec0) at new_allocator.h:153:10
    frame #2: 0x0000555555555dbd prog`void std::allocator_traits<std::allocator<Test>>::destroy<Test>(__a=0x000055555556cec0, __p=0x000055555556cec0) at alloc_traits.h:497:8
    frame #3: 0x0000555555555bd6 prog`std::_Sp_counted_ptr_inplace<Test, std::allocator<Test>, (__gnu_cxx::_Lock_policy)2>::_M_dispose(this=0x000055555556ceb0) at shared_ptr_base.h:557:2
    frame #4: 0x0000555555555503 prog`std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release(this=0x000055555556ceb0) at shared_ptr_base.h:155:6
    frame #5: 0x00005555555554ba prog`std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(this=0x00007fffffffe4e0) at shared_ptr_base.h:730:11
    frame #6: 0x0000555555555579 prog`std::__shared_ptr<Test, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr(this=0x00007fffffffe4d8) at shared_ptr_base.h:1169:31
    frame #7: 0x0000555555555465 prog`std::shared_ptr<Test>::~shared_ptr(this=nullptr) at shared_ptr.h:103:11
    frame #8: 0x000055555555524f prog`main at prog.cc:16:1
    frame #9: 0x00007ffff7a9c0b3 libc.so.6`__libc_start_main + 243
    frame #10: 0x000055555555514e prog`_start + 46

Maybe stopping in a callee suffices, or maybe seeing the desired symbol and its file name in the backtrace helps accomplish the goal.

Documentation link

I got most of this info by reading the Breakpoint commands section of the GDB to LLDB command map, plus experimentation.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?