【问题标题】:AIX library calls to get thread info / statusAIX 库调用以获取线程信息/状态
【发布时间】:2012-02-18 00:07:54
【问题描述】:

是否有任何 AIX 运行时库调用可供我在 AIX 上的 C++ 中使用来监视与正在运行的进程关联的线程的状态?我正在尝试解决一个我认为是由于程序在所有线程加入之前退出导致的关机崩溃问题。

我明白在多线程环境中,准确记录线程的状态并不容易,因为它们很可能在读取状态和显示状态之间发生了变化,但是任何东西(无论多么粗糙)都可以用作追踪此事的第一步。

【问题讨论】:

  • ITtoolbox.com 上的组下有一个强大的 AIX 支持社区。 (我在那里没有经济利益,我只是一个注册用户)。祝你好运。

标签: c++ multithreading aix


【解决方案1】:

您说“关闭时崩溃”...您是指带有崩溃转储的系统崩溃吗?如果是这样,那么您拥有大量数据。如果您需要,我会使用以下命令启动系统跟踪大缓冲区。系统崩溃并重新启动后,您可以使用 trcdead 从转储中吸取跟踪缓冲区。此外,您还可以了解系统的状态。

不应该是愚蠢的线程导致系统崩溃。

【讨论】:

  • 进程在被指示正常关闭时崩溃。这不是系统崩溃。抱歉,如果不清楚。
  • 射击。我用这个假设输入了一个很长的回复,然后将其删除。让我为你重做。
【解决方案2】:

首先,有一个系统跟踪工具。我没有从应用程序中使用太多(任何?),但它是线程安全的。

http://pic.dhe.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.genprogc/doc/genprogc/trace_facility.htm#yg3100thri

http://pic.dhe.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.genprogc/doc/genprogc/tracing.htm?resultof=%22%61%70%70%6c%69%63%61%74%69%6f%6e%22%20%22%61%70%70%6c%69%63%22%20%22%74%72%61%63%65%22%20

如果这是一个非常复杂的应用程序,我会连接真正的跟踪挂钩并开发一个跟踪格式文件。花时间是值得的。下面是一个比较粗略的方法。

我可能会跟踪此问题的方法是连接一个自制的跟踪或日志设施。在代码中,调用日志例程。然后返回并检查核心文件,挖掘日志缓冲区,这将告诉您您命中的日志点的顺序。

这可能是一个迭代过程,您在其中添加一些点,然后确定您需要在代码的特定部分中添加更多点并在那里添加日志点。再试一次。重复。

日志例程实际上非常简单,并利用了原子操作之一。我正在使用 fetch_and_add。

long array[4096];       /* some power of 2 in size is my preference */
unsigned int index;     /* int -- not a long */

/* trace 5 words each time. */
void log(long *a, long b, long c, long d, long e)
{
  /*
   * the 5 equals the number of args.  The 4095 is one less than the
   * size of the array.  You can use mod if you want.  Also, note that
   * there are flavors of fetch_and_add for different sized
   * variables.  Pick the one that matches the size of index.
   */
  int i = fetch_and_add(&indx, 5) & 4095; 

  /*
   * at this point, array[i] ... array[i+4] have been effectively
   * reserved.  The time taken between the fetch_and_add and updating
   * the array does not need to be atomic or locked.  The only
   * possible exception is you don't want the log to wrap within this
   * time but that would be very unlikely.
   */

  array[i] = *a;
  array[i+1] = b;
  array[i+2] = c;
  array[i+3] = d;
  array[i+4] = e;
}

/* your original code spinkle calls to log */
int whatever(long arg1, int arg2)
{
  log("WHT1", arg1, arg2, 0, 0);

  foo = apple + pie;
  bar = whisky + good;
  dog = nice + pet;
  cat = meow;

  log("WHT2", foo, bar, log, dog);

  /* ... */
}

第一个参数的诀窍是,当您获取核心文件并转储数组时,您可以将其转储为十六进制和文本。从文本输出中,您可以快速查看正在调用哪些日志点。如果你有一个 64 位的应用程序,你可以使用 8 个字符,而不是限制为 4 个字符。

注意index的值是core文件中的key。这会告诉您最后一个被击中的日志点。然后后退一步通过日志数组查看之前的日志点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2020-09-12
    • 1970-01-01
    相关资源
    最近更新 更多