Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 如何正确编写调用AsyncGetCallTrace的SIGPROF处理程序?_Asynchronous_Profiling_Signal Handling_Jvmti - Fatal编程技术网

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

Asynchronous 如何正确编写调用AsyncGetCallTrace的SIGPROF处理程序?,asynchronous,profiling,signal-handling,jvmti,Asynchronous,Profiling,Signal Handling,Jvmti,我正在编写一个简短的分析器(用C编写),它旨在定期打印各种Java客户机中线程的堆栈跟踪。我必须使用未记录的函数AsyncGetCallTrace而不是GetStackTrace,以最小化入侵并允许堆栈跟踪,而不管线程状态如何。该函数的源代码可在此处找到: 在hotspot/src/share/vm/prims/forte.cpp中。我找到了一些记录JVMTI、信号处理和计时的手册页,以及一个关于如何设置AsyncGetCallTrace调用的详细信息的博客: 本博客缺少的是在信号处理程序中实际

我正在编写一个简短的分析器(用C编写),它旨在定期打印各种Java客户机中线程的堆栈跟踪。我必须使用未记录的函数
AsyncGetCallTrace
而不是
GetStackTrace
,以最小化入侵并允许堆栈跟踪,而不管线程状态如何。该函数的源代码可在此处找到: 在hotspot/src/share/vm/prims/forte.cpp中。我找到了一些记录JVMTI、信号处理和计时的手册页,以及一个关于如何设置
AsyncGetCallTrace
调用的详细信息的博客:

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

以上问题是我面临的主要问题。然而,我面临的其他问题包括:

  • SIGPROF
    似乎不是由计时器精确地在指定的时间间隔触发的,而是频率较低。也就是说,如果我将计时器设置为每秒发送一个
    SIGPROF
    (1秒,0 usec),那么在5秒钟的运行中,我得到的处理程序输出少于5个(通常为1-3)

  • SIGPROF
    处理程序输出在Java代码中的
    线程睡眠期间根本不会出现。所以,如果每秒发送一个
    SIGPROF
    ,我有
    Thread.sleep(5000),在执行该代码期间,我将不会获得任何处理程序输出


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

    我最终得到了一个积极的结果,但由于这里很少讨论,我自己的回答将是简短的

    ASGCT_CallTrace结构(以及底层ASGCT_CallFrame数组)可以简单地在信号处理程序中声明,因此仅存在堆栈: ASGCT_调用跟踪; JNIEnv*env; 全局虚拟机指针->AttachCurrentThread((void**)和环境,NULL); trace.env_id=env; trace.num_frames=0; ASGCT_调用帧存储[25]; trace.frames=存储

    以下内容获取uContext: ucontext\u t ucontext; getcontext(&uContext)

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

    我确信在这个过程中我还需要注意一些其他的细微差别,但我并没有真正记录它们。我不确定我是否能够公开我目前拥有的全部代码,这些代码成功地以固定的时间间隔异步请求并获取任何java程序的堆栈跟踪。但如果有人对同一个问题感兴趣或陷入困境,我现在可以提供帮助(我想)

    关于其他两个问题: [1] 如果一个线程正在睡眠,并且生成了一个SIGPROF,那么该线程只有在醒来后才会处理该信号。这是正常的,因为处理信号是线程的工作。
    [2] 计时器的缺陷似乎不再出现。也许我量错了。

    我帮不了你,但你的努力太棒了!另外,您希望它具有最小的侵入性,但我认为它实际上不需要,因为不需要太多的样本。您应该确保它可以在等待I/O时采集样本。关于这个问题,这里有一个通用的例子:事实上,几年前我在C中使用的方法是使用SIGALRM。无论线程是否被阻塞,您都需要触发的东西。而且,如果它不是特别准确,那也没关系。重要的是程序对取样时间没有影响。@Mike Dunlavey:谢谢你提供的信息,但是建议的方法可能有一些问题:1。我想自动化并推广这个分析过程。也就是说,我的JVMTI代码可以在任何Java客户机上运行,只需要提到一个jvmarg(即.so文件)。每次手动休息都会耗费时间,而且系统性较差。我的目标是对程序进行微调,以向服务器提供每秒100到1000次的事务。不管你链接中的帖子怎么说,我认为对于这些程序来说,更大的样本量和更细粒度和一致性的堆栈跟踪轮询是更好的选择。如果你认为这个论点不正确,请纠正我。3.关于SIGALRM方法:我不确定在我的案例中准确性是我想忽略的,但我可以更深入地研究它。尽管如此,我仍然在寻找使用AsyncGetCallTrace的解决方案。所以如果你听到什么,请告诉我。再次感谢。这里有分析器,RotateRight/Zoom和LTProf,如果你做他们做的事情,我认为你在正确的轨道上。他们在墙上时钟(而不是cpu)时间对调用堆栈进行采样。它们报告每行(非函数)包含该行的堆栈样本的百分比。一条线在堆栈上的时间分数正是如果可以避免或删除该线,可以节省多少墙时间。因为目标是找到你不需要的昂贵的线,它们由堆栈样本精确定位。测量它们的精度是一个品味的问题,但发现是目标。