如何正确编写调用AsyncGetCallTrace的SIGPROF处理程序?

时间:2010-08-06 18:11:55

标签: asynchronous profiling signal-handling jvmti

我正在编写一个简短的简单探查器(在C中),它旨在定期打印各种Java客户端中的线程的堆栈跟踪。我必须使用未记录的函数AsyncGetCallTrace而不是GetStackTrace来最小化入侵并允许堆栈跟踪,而不管线程状态如何。该函数的源代码可以在这里找到:http://download.java.net/openjdk/jdk6/promoted/b20/openjdk-6-src-b20-21_jun_2010.tar.gz 在hotspot / src / share / vm / prims / forte.cpp中。我找到了一些记录JVMTI,信号处理和时序的手册页,以及一个详细介绍如何设置AsyncGetCallTrace调用的博客:http:// jeremymanson.blogspot.com/2007/05/profiling-with-jvmtijvmpi- SIGPROF-and.html。

这个博客缺少的是在信号处理程序中实际调用该函数的代码(作者假设读者可以自己完成此操作)。我正在寻求帮助来做到这一点。我不确定如何以及在何处创建结构ASGCT_CallTrace(以及内部结构ASGCT_CallFrame),如上述文件forte.cpp中所定义。 struct ASGCT_CallTrace是传递给AsyncGetCallTrace的参数之一,因此我需要创建它,但我不知道如何为其字段获取正确的值:JNIEnv * env_id,jint num_frames和JVMPI_CallFrame 帧。此外,我不知道传递给AsyncGetCallTrace(void ucontext)的第三个参数应该是什么?

上述问题是我的主要问题。但是,我面临的其他问题包括: [1]定时器似乎没有在指定的时间间隔内提出信号,而是频繁出现。也就是说,如果我将定时器设置为每秒发送一个SIGPROF(1秒,0 usec),那么在5秒运行中,我得到的SIGPROF处理器输出少于5个(通常为1-3个) [2]在Java代码的Thread.sleep期间,根本不出现SIGPROF处理程序输出。因此,如果要每秒发送一个SIGPROF,并且我有Thread.sleep(5000);,那么在执行该代码期间我不会获得任何处理程序输出。

任何帮助将不胜感激。其他详细信息(以及代码和示例输出的部分)将根据要求发布。

谢谢!

1 个答案:

答案 0 :(得分:1)

我终于得到了一个积极的结果,但由于在这里产生了很少的讨论,我自己的答案很简短。

ASGCT_CallTrace结构(以及底层的ASGCT_CallFrame数组)可以简单地在信号处理程序中声明,因此只存在堆栈: ASGCT_CallTrace跟踪; JNIEnv * env; global_VM_pointer-> AttachCurrentThread((void **)& env,NULL); trace.env_id = env; trace.num_frames = 0; ASGCT_CallFrame存储[25]; trace.frames = storage;

以下获取uContext: ucontext_t uContext; 的getContext(安培; uContext);

然后电话就是: AsyncGetCallTrace(& trace,25,& uContext);

我确信在此过程中我还有其他一些细微差别需要处理,但我并没有真正记录它们。我不确定我是否可以透露我现有的完整代码,它们以固定的时间间隔成功异步请求并获取任何java程序的堆栈跟踪。但如果有人对同一问题感兴趣或坚持,我现在能够提供帮助(我认为)。

另外两个问题: [1]如果线程正在休眠并且生成了SIGPROF,则线程仅在唤醒后处理该信号。这是正常的,因为处理信号是线程的工作。 [2]计时器瑕疵似乎不再出现了。也许我误解了。