首先,有一个系统跟踪工具。我没有从应用程序中使用太多(任何?),但它是线程安全的。
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。这会告诉您最后一个被击中的日志点。然后后退一步通过日志数组查看之前的日志点。