我想通过控制哪些线程执行来调试多线程程序。我正在使用C ++和gdb。除主线程之外我有两个线程(对于示例程序),我想调试一个线程,同时保持另一个线程停止。
以下是我写的示例程序:
#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#define NUM_THREADS 2
using namespace std;
void * run (void *) {
for (int i = 0; i < 3; ++i) {
sleep(1);
cout << i << " " << pthread_self() << endl;
}
pthread_exit(NULL);
}
int main (int argc, char** argv) {
cout << "Start..." << endl;
int rc;
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; ++i) {
rc = pthread_create(&threads[i], NULL, run, NULL);
if (rc) {
cout << "pthread_create returned error: " << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
我运行gdb并将断点设置为sleep(1)
。然后我运行程序。我得到三个线程(线程2和3是pthreads),程序在线程2(等待sleep(1)
)。现在,我希望将线程3保留在任何地方,并继续单步执行线程2(通过在gdb中执行c
)。
我尝试的是set scheduler-locking on
,但似乎没有按照我的预期运作。我在线程2,我set scheduler-locking on
,continue
几次(到目前为止很好,我仍在线程2中),切换到线程3,set scheduler-locking on
,{{1}由于某种原因,我回到第2个线程......当我不应该(根据我的理解)。有什么我想念的吗?
答案 0 :(得分:8)
看起来调度程序锁定仅在单步或下一步时有用。一旦你继续你当前的线程,它们都会运行,并且下一个到达断点的线程将获取提示。至少,这是我对手册的解释:
http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_node/gdb_39.html
因此,一旦你进入线程3,其他线程就会被停止,只要你一步/下一步,它们就不会运行。但是一旦你继续,它们都会运行,并且下一个线程(在你的例子中为2)击中睡眠中的断点(1)将获取提示。
也许让所有线程都进入睡眠状态,但是一次只能继续其中一个线程。
答案 1 :(得分:6)
正如TazMainiac所说,调度程序锁定对于单步执行非常有用,但“模式”必须设置为“步进”。
set scheduler-locking step
您可以参考TazMainiac提供的链接,提及相同的内容:
http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_node/gdb_39.html
步进模式优化单步执行。它会阻止其他线程 通过在您之前抢占当前线程来“抓住提示” 正在踩着。