如何配置 lldb 在多个线程逐一命中的断点处停止?

问题描述 投票:0回答:1

我有一个简单的 macOS 应用程序,它生成 14 个运行相同函数的线程。 如果我在函数内设置断点,并从命令行 lldb 中运行应用程序,而不是逐一中断该位置,lldb 会报告多个线程已停止在那里(不是全部,每次都是随机的)。

我可以在 lldb 中设置一些设置,以确保它一次断点一个线程,而不是全部断点吗?

这是 lldb 的一些示例输出,其中显示多个线程在同一个初始断点处停止

lldb -- /Users/alex/Dev/projects/builds/build-simple_test_app-Qt_6_8_0_mac_official_2-Debug/simple_test_app.app/Contents/MacOS/simple_test_app
(lldb) target create "/Users/alex/Dev/projects/builds/build-simple_test_app-Qt_6_8_0_mac_official_2-Debug/simple_test_app.app/Contents/MacOS/simple_test_app"

Current executable set to '/Users/alex/Dev/projects/builds/build-simple_test_app-Qt_6_8_0_mac_official_2-Debug/simple_test_app.app/Contents/MacOS/simple_test_app' (arm64).

(lldb) b /Users/alex/Dev/qtcreator/worktrees/qtcreatordev/tests/manual/debugger/simple/simple_test_app.cpp:4209
Breakpoint 1: where = simple_test_app`qthread::Thread::run() + 24 at simple_test_app.cpp:4209:17, address = 0x000000010002e734

(lldb) run
Process 24223 launched: '/Users/alex/Dev/projects/builds/build-simple_test_app-Qt_6_8_0_mac_official_2-Debug/simple_test_app.app/Contents/MacOS/simple_test_app' (arm64)
warning: 'QtCore' contains a debug script. To run this script in this debug session:

    command script import "/Users/alex/Dev/qt/official/6.8.0/macos/lib/QtCore.framework.dSYM/Contents/Resources/Python/QtCore.py"

To run all discovered debug scripts in this session:

    settings set target.load-script-from-symbol-file true

2024-10-15 15:45:48.832326+0200 simple_test_app[24223:2627260] '\u1e9e' true
2024-10-15 15:45:48.832341+0200 simple_test_app[24223:2627260] Creator: Switch off magic autorun.
2024-10-15 15:45:48.936005+0200 simple_test_app[24223:2627260] qDebug() 1
2024-10-15 15:45:48.936011+0200 simple_test_app[24223:2627260] qDebug() 2
2024-10-15 15:45:48.936014+0200 simple_test_app[24223:2627260] qDebug() 3
2024-10-15 15:45:48.936016+0200 simple_test_app[24223:2627260] qDebug <foo & bar>
std::cout @@ 1
std::cout @@ 2
std::cout @@ 3
std::cout <foo & bar>
std::cerr 1
std::cerr 2
std::cerr 3
std::cerr <foo & bar>
2024-10-15 15:45:48.937637+0200 simple_test_app[24223:2627260] SENDER:  qobject::Sender(0x16fdfdb70, name = "Sender")
2024-10-15 15:45:48.938025+0200 simple_test_app[24223:2627260] "HiDu"
Process 24223 stopped
* thread #6, name = 'Thread #0', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfda28) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
  thread #7, name = 'Thread #1', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfda40) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
  thread #8, name = 'Thread #2', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfda58) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
  thread #9, name = 'Thread #3', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfda70) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
  thread #10, name = 'Thread #4', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfda88) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
  thread #11, name = 'Thread #5', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfdaa0) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
  thread #12, name = 'Thread #6', stop reason = breakpoint 1.1
    frame #0: 0x000000010002e734 simple_test_app`qthread::Thread::run(this=0x000000016fdfdab8) at simple_test_app.cpp:4209:17
   4206
   4207         void run() override
   4208         {
-> 4209             int j = 2;
   4210             ++j;
   4211             for (int i = 0; i != 1000; ++i) {
   4212                 //sleep(1);
Target 0: (simple_test_app) stopped.
lldb
1个回答
0
投票

这实际上就是向 lldb 报告事件的方式。 当 lldb 获取一个线程的停止事件时,还会报告多个其他线程在相同甚至多个不同的断点处停止。 正如您所观察到的,这似乎是随机的,具体取决于内核如何调度您的进程。 没有办法告诉内核序列化断点异常的报告。

早期,lldb 试图向您隐藏这一事实,并假装命中是序列化的,但这最终导致了错误,而且更令人困惑而不是有用,所以它只是报告内核所说的真实情况。

© www.soinside.com 2019 - 2024. All rights reserved.