【发布时间】:2014-09-12 16:13:40
【问题描述】:
我正在尝试调试服务器应用程序,但我在需要时遇到了一些困难。该应用程序分为两部分:
- 一个服务器应用程序,它产生工作进程(不是线程)来处理传入的请求。服务器基本上会产生进程,这些进程将处理传入的请求,先到先得。
- 服务器还以共享库的形式加载插件。共享库定义了服务器能够处理的大部分服务,因此大部分实际处理都在这里完成。
作为一个额外的乐趣,工作进程“重生”(即退出并产生一个新的工作进程),因此子进程的 PID 会定期更改。 -_-'
基本上我需要调试在共享库中调用的服务,但我不知道要提前附加到哪个进程,因为它们会临时获取请求。到目前为止,附加到主进程并设置断点似乎没有用。
有没有一种方法可以调试这个共享库代码而无需提前附加到进程?基本上我想调试调用相关函数的第一个进程。
目前我可能会尝试将工作进程的数量限制为 1 且不重生,但最好知道将来如何处理这样的场景,尤其是如果我想确保它在“发布”配置中仍然有效。
我正在尝试使用 DDD 和 GDB 进行调试的 Linux 平台上运行。
编辑:为了帮助说明我想要完成的工作,让我提供一个简短的概念证明。
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int important_function( const int child_id )
{
cout << "IMPORTANT(" << child_id << ")" << endl;
}
void child_task( const int child_id )
{
const int delay = 10 - child_id;
cout << "Child " << child_id << " started. Waiting " << delay << " seconds..." << endl;
sleep(delay);
important_function(child_id);
exit(0);
}
int main( void )
{
const int children = 10;
for (int i = 0; i < 10; ++i)
{
pid_t pid = fork();
if (pid < 0) cout << "Fork " << i << "failed." << endl;
else if (pid == 0) child_task(i);
}
sleep(10);
return 0;
}
这个程序将派生 10 个进程,这些进程将在调用 important_function 之前全部休眠 10 - id 秒,这是我想在第一个调用子进程中调试的函数(这里应该是我派生的最后一个)。
将 follow-fork-mode 设置为 child 将让我跟随第一个孩子分叉,这不是我想要的。我正在寻找第一个调用重要函数的孩子。
关闭 detach-on-fork 并没有帮助,因为它会暂停父进程,直到子进程 fork 退出,然后再继续 fork 其他进程(一次一个,在最后一个退出之后)。
在实际场景中,我能够附加到已经产生线程的已经运行的服务器应用程序上,并在第一个调用该函数的应用程序上停止,这一点也很重要。
我不确定这是否可行,因为我没有看到太多关于它的文档。基本上我想调试第一个应用程序来调用这行代码,不管它来自什么进程。 (虽然只有我的应用程序进程会调用代码,但似乎我的问题可能更普遍:附加到调用代码的第一个进程,无论其来源如何)。
【问题讨论】:
标签: c++ c gdb multiprocessing