【问题标题】:Get call stack from any thread within C从 C 中的任何线程获取调用堆栈
【发布时间】:2010-11-21 14:13:40
【问题描述】:

在 Solaris 10 上的 C 中,我想从进程中的任意线程获取调用堆栈。

我有许多工作线程和一个监视所有工作线程以检测紧密循环和死锁的线程。我想实现的功能是让监控线程在杀死它之前多次从“挂起”线程打印调用堆栈。

我知道如何通过让监控线程执行 pstack(使用 system() 或通过分叉)来实现这一点。但是我希望能够在 C 中实现这个功能。有没有办法做到这一点?

我知道如何通过遍历堆栈使线程打印其 OWN 调用堆栈,这在它遇到断言时很有用,但不知道如何为同一进程中的另一个线程执行此操作。

感谢您的帮助。 尼克B

【问题讨论】:

    标签: c multithreading stack solaris call


    【解决方案1】:

    您可以使用walkcontext() 遍历堆栈,使用dladdr()/dladdr1() 将地址转换为函数名称。 walkcontext() 采用 ucontext 作为线程。如果您没有该线程的合作,那么您可以通过停止线程(例如使用PCTWSTOP)然后从该线程的lwpstatus结构的pr_oldcontext字段中读取其地址来获取它的ucontext,获得来自/proc/self/lstatus

    【讨论】:

      【解决方案2】:

      如果您使用 gcc,您可以使用内置函数 __builtin_return_address。 void * __builtin_return_address (unsigned int level)

      函数返回调用函数的函数地址。即函数的调用者。

      级别指定了多少级别。 0 表示当前函数 1 表示调用者,2 表示调用者调用者。 以下示例将提供用法。通过打印函数的地址,可以确定调用堆栈。

      int calla()
      {
         printf("Inside calla\n");
         printf("A1=%x\n",__builtin_return_address (0));
         printf("A2=%x\n",__builtin_return_address (1) );
         printf("A3=%x\n",__builtin_return_address (2) );
      }
      int callb()
      {
          printf("Inside callb\n");
          calle();
          printf("B1=%x\n",__builtin_return_address (0) );
          printf("B2=%x\n",__builtin_return_address (1) );
          printf("B3=%x\n",__builtin_return_address (2) );
      }
      int callc()
      {
          printf("Inside callc\n");
          printf("C1=%x\n",__builtin_return_address (0) );
          printf("C2=%x\n",__builtin_return_address (1) );
          printf("C3=%x\n",__builtin_return_address (2) );
      }
      int calld()
      {
          printf("Inside calld\n");
          printf("D1=%x\n",__builtin_return_address (0) );
          printf("D2=%x\n",__builtin_return_address (1) );
          printf("D3=%x\n",__builtin_return_address (2) );
      }
      int calle()
      {
          printf("Inside calle\n");
          printf("E1=%x\n",__builtin_return_address (0) );
          printf("E2=%x\n",__builtin_return_address (1) );
          printf("E3=%x\n",__builtin_return_address (2) );
      }
      main()
      {
          printf("Address of main=%x calla=%x callb=%x callc=%x calld=%x calle=%x\n",main,calla,callb,callc,calld,calle);
          calla();
          callb();
          calld();
      }
      

      【讨论】:

      • 但这如何允许一个线程从另一个线程获取调用堆栈?
      猜你喜欢
      • 2014-10-13
      • 2011-03-23
      • 1970-01-01
      • 2017-11-27
      • 2014-03-12
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      相关资源
      最近更新 更多