C++ GDB/DDD:使用多进程应用程序C/C+调试共享库+;
我试图调试一个服务器应用程序,但在需要的地方遇到了一些困难。该应用程序分为两部分:C++ GDB/DDD:使用多进程应用程序C/C+调试共享库+;,c++,c,gdb,multiprocessing,C++,C,Gdb,Multiprocessing,我试图调试一个服务器应用程序,但在需要的地方遇到了一些困难。该应用程序分为两部分: 一个服务器应用程序,它生成工作进程(而不是线程)来处理传入的请求。服务器基本上会产生一些进程,这些进程将处理先到先得的传入请求 服务器还以共享库的形式加载插件。共享库定义了服务器能够处理的大部分服务,因此大部分实际处理在这里完成 作为一种额外的喜悦,工作者处理“重生”(即退出并产生一个新的工作者进程),因此孩子们的PID会定期变化 基本上,我需要调试在共享库中调用的服务,但我不知道要提前附加到哪个进程,因为它
- 一个服务器应用程序,它生成工作进程(而不是线程)来处理传入的请求。服务器基本上会产生一些进程,这些进程将处理先到先得的传入请求
- 服务器还以共享库的形式加载插件。共享库定义了服务器能够处理的大部分服务,因此大部分实际处理在这里完成
#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;
}
#包括
#包括
#包括
使用名称空间std;
int重要函数(const int child_id)
{
cout您可以在fork()处设置断点,然后发出“continue”命令,直到主进程的下一步是生成要调试的子进程。此时,在要调试的函数处设置断点,然后发出“set follow fork mode child”当您继续时,gdb应该将您挂接到断点所在函数处的子进程中
如果发出命令“将分离设置为打开或关闭”,gdb将继续调试子进程。到达库中断点的进程应在到达该断点时停止。问题是,当“fork上的分离”处于禁用状态时,gdb将在启动时停止所有分叉的子进程。我不知道如何告诉它在分叉后继续执行这些进程
我认为解决这个问题的一个方法是编写一个toswitch到每个进程并发出continue命令。用断点命中函数的进程应该停止
一位同事提供了另一种解决方案来解决让每个子进程继续的问题。您可以打开“detach on fork”,在每个子进程的入口点插入一条打印出其进程id的打印语句,然后给它一条语句,告诉它等待变量中的更改,如下所示:
{
volatile int foo = 1;
printf("execute \"gdb -p %u\" in a new terminal\n", (unsigned)getpid());
printf("once GDB is loaded, give it the following commands:\n");
printf(" set variable foo = 0\n");
printf(" c\n");
while (foo == 1) __asm__ __volatile__ ("":::"memory");
}
然后,启动gdb,启动主进程,并将输出通过管道传输到一个文件。使用bash脚本,您可以读入子进程的进程ID,启动多个gdb实例,将每个实例附加到一个不同的子进程,并通过清除变量“foo”来通知每个子进程继续.问题是,我不知道哪个子进程将接受和处理服务器请求。这不是以确定的方式完成的;相反,进程等待传入的连接,然后尝试接受它,因此,在空闲进程中,谁能得到它取决于谁有幸在请求传入时运行。嗯,fork-off上的detach的问题是follow-fork模式的子进程似乎会停止父进程,直到子进程停止。因此,作为一个简单的概念证明,我编写了一个应用程序,该应用程序分叉10个子进程,每个子进程在唤醒和调用我想要调试的函数之前休眠10 id秒(因此最后一个分叉的螺纹(通常)首先到达目标。启用“分离”后,我将只在第一个生成的线程上进行调试。禁用该选项后,我将不得不按顺序调试所有线程,这也不是我所需要的。我建议关闭“跟随分叉”模式,并关闭“分离”分叉。这将继续父进程,并在子进程启动后立即停止所有子进程。要使所有子进程继续运行,您可以切换到每个子进程并发出“continue”命令。目前我知道的唯一避免为每个进程手动执行此操作的方法是编写一个gdb脚本来执行此操作,正如我在上面的回答中所建议的。为了使其有用,它不需要为了调试目的而更改代码。我希望能够在没有错误的情况下停止正确的进程)必须添加额外的调试代码(如提供的代码),b)必须在每个进程上继续(即在附加时停止进程,然后继续,稍微更改应用程序的操作),或c)要求我必须使用gdb启动主应用程序(例如,调试已在运行的服务器)。我希望任何进程的共享库代码中都会出现更多的通用暂停,但这看起来不太可能。:/最适合我的方法是只启动一个工作线程进行调试。但从理论上讲,您所建议的应该是可以协调的。