SA's JStack vs JDK's JStack

  • Linux Signals

    • Standard Signals

      Linux supports the standard signals listed below. Several signal
      numbers are architecture-dependent, as indicated in the "Value"
      column. (Where three values are given, the first one is usually
      valid for alpha and sparc, the middle one for x86, arm, and most
      other architectures, and the last one for mips.

      • table
        • Signal Value Action Comment
        • SIGKILL 9 Term Kill signal
        • SIGSTOP 17,19,23 Stop Stop process
    • signal.h

      • partial
        • define SIGQUIT 3

        • define SIGKILL 9

        • define SIGSTOP 19

    • Signal Descriptions

      • SIGKILL
        • The SIGKILL signal forces the process to stop executing immediately. The program cannot ignore this signal. This process does not get to clean-up either.
      • SIGQUIT
        • This is like SIGINT with the ability to make the process produce a core dump.
      • SIGSTOP
        • This signal makes the operating system pause a process's execution. The process cannot ignore the signal.
    • kill -l (kill -9 pid)

        1. SIGQUIT
        1. SIGKILL
        1. SIGSTOP
  • References


  • ptrace

    • process trace
    • The ptrace() system call provides a means by which one process (the
      "tracer") may observe and control the execution of another process
      (the "tracee"), and examine and change the tracee's memory and
      registers. It is primarily used to implement breakpoint debugging
      and system call tracing.
    • long ptrace(enum __ptrace_request request,
      pid_t pid, 指示ptrace要跟踪的进程
      void *addr, 指示要监控的内存地址
      void *data);存放读取出的或者要写入的数据
      • PTRACE_ATTACH
        • Attach to the process specified in pid, making it a tracee of
          the calling process. The tracee is sent a SIGSTOP, but will
          not necessarily have stopped by the completion of this call;
          use waitpid(2) to wait for the tracee to stop. See the
          "Attaching and detaching" subsection for additional
          information. (addr and data are ignored.)
      • ptrace(PTRACE_ATTACH, pid, 0, 0);
    • 你是否曾经想过怎样才能拦截系统调用?你是否曾经想过通过修改一下系统调用的参数来耍一把内核?你是否想过调试器是怎样把一个进程停下来,然后把控制权转移给你的?如果你以为这些都是通过复杂的内核编程来实现的,那你就错了,事实上,Linux 提供了一种很优雅的方式来实现上述所有行为:ptrace 系统调用。ptrace 提供了一种机制使得父进程可以观察和控制子进程的执行过程,ptrace 还可以检查和修改该子进程的可执行文件在内存中的镜像及该子进程所使用的寄存器中的值。这种用法通常来说,主要用于实现对进程插入断点和跟踪子进程的系统调用。
    • ptrace函数可能会让人们觉得很奇特,因为它居然可以检测和修改一个运行中的程序。这种技术主要是在调试器和系统调用跟踪程序中使用。它使程序员可以在用户级别做更多有意思的事情。已经有过很多在用户级别下扩展操作系统得尝试,比如UFO,一个用户级别的文件系统扩展,它使用ptrace来实现一些安全机制。
    • 进程状态TASK_TRACED用以表示当前进程因为被父进程跟踪而被系统停止
    • gdb是我们调试程序的利器,strace可以方便的帮助我们记录进程所执行的系统调用 都是基于ptrace实现的;
  • References


  • proc

    • process information pseudo-filesystem
    • Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。
      proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
      它以文件系统的方式为访问系统内核数据的操作提供接口
    • The proc filesystem is a pseudo-filesystem which provides an
      interface to kernel data structures. It is commonly mounted at
      /proc. Most of it is read-only, but some files allow kernel
      variables to be changed.
    • Files and directories
      • /proc/[pid]
      • There is a numerical subdirectory for each running process; the subdirectory is named by the process ID.
      • /proc/[pid]/maps
      • A file containing the currently mapped memory regions and their access permissions
    • The format of the file is

    address perms offset dev inode pathname
    00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
    00651000-00652000 r--p 00051000 08:02 173521 /usr/bin/dbus-daemon

     00652000-00655000 rw-p 00052000 08:02 173521      /usr/bin/dbus-daemon
     00e03000-00e24000 rw-p 00000000 00:00 0           [heap]
     00e24000-011f7000 rw-p 00000000 00:00 0           [heap]
     ...
     35b1800000-35b1820000 r-xp 00000000 08:02 135522  /usr/lib64/ld-2.15.so
     35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522  /usr/lib64/ld-2.15.so
     35b1a20000-35b1a21000 rw-p 00020000 08:02 135522  /usr/lib64/ld-2.15.so
     35b1a21000-35b1a22000 rw-p 00000000 00:00 0
     35b1c00000-35b1dac000 r-xp 00000000 08:02 135870  /usr/lib64/libc-2.15.so
     35b1dac000-35b1fac000 ---p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
     35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
     35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870  /usr/lib64/libc-2.15.so
     ...
     f2c6ff8c000-7f2c7078c000 rw-p 00000000 00:00 0    [stack:986]
     ...
     7fffb2c0d000-7fffb2c2e000 rw-p 00000000 00:00 0   [stack]
     7fffb2d48000-7fffb2d49000 r-xp 00000000 00:00 0   [vdso]
    
  • References


  • HotSpot Serviceability Agent

    • JStack
      • HotSpot Serviceability Agent?简单来讲SA就是HotSpot提供的一套JavaAPI,通过这套API我们可以获取一个目标JVM的运行时信息,这套API的代码在$JAVA_HOME/lib/sa-jdi.jar中,源码的话是在hotspot工程的agent目录下: openjdk/hotspot/agent/***
      • 介绍SA中的一个工具jstack。咦,jstack,好眼熟,是的,在JDK自带的工具中也有一个jstack,我们平时用的也都是它。在SA中也有一个JStack,二者实现的机制完全不一样
      • JDK's JStack (openjdk/jdk/src/share/classes/sun/tools/jstack/JStack.java)
        • 在jdk工程下发现了sun.tools.jstack.JStack,应该就是jstack命令的源码了。我们来跑下试下。这个类是在$JAVA_HOME/lib/tools.jar中。先把环境变量配置好
        • 2132是通过jps命令看到的另一个Java进程的pid
        • java sun.tools.jstack.JStack 2132
        • 上面已经说到了两个jstack实现的机制是完全不一样的,SA中的jstack当然是通过SA的机制实现的,那么JDK中的jstack又是通过什么机制呢?其实是通过了另一个HotSpot提供的,Dynamic Attach机制(跟SA二者都是HotSpot的私有机制,不是JVM标准),具体这个机制是怎么实现的,这里暂不展开,有兴趣的同学可以看看笨神博客还有官方文档。
      • SA's JStack (openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java)
        • java sun.jvm.hotspot.tools.JStack 2132
        • 看上去还是JDK自带的jstack输出友好一点。
        • 加上-Dsun.jvm.hotspot.bugspot.BugSpotAgent.DEBUG=true选项会多输出一行,SA's JVMDI,这个又是什么鬼?暂不深究哈,还有SA的实现机制,留待后续再作探讨。
      • JDK's JStack实现分析
        • This class is the main class for the JStack utility. It parses its arguments and decides if the command should be executed by the SA JStack tool or by obtained the thread dump from a target process using the VM attach mechanism
          if (useSA) {//使用SA runJStackTool(mixed, locks, params); - runJStackTool(){//反射调用 // JStack tool also takes -m and -l arguments Class cl = Class.forName("sun.jvm.hotspot.tools.JStack", true, ClassLoader.getSystemClassLoader()); Method m = cl.getDeclaredMethod("main", { String[].class }); m.invoke(null, { args }); } } else { runThreadDump(pid, params); - runThreadDump(){ // Attach to pid and perform a thread dump VirtualMachine vm = VirtualMachine.attach(pid); // Cast to HotSpotVirtualMachine as this is implementation specific method. InputStream in = ((HotSpotVirtualMachine)vm).remoteDataDump((Object[])args); //读取n = in.read(b); vm.detach(); } }
        • 哪些情况下使用SA's JStack?
          • -F
          • -m
          • Next we check the parameter count. If there are two parameters we assume core file and executable so we use SA.
          • 参数的值不能匹配数字[0-9]+ //If we can't parse it as a pid then it must be debug server
        • SA non-supported
          • jstack [-l] <pid> to connect to running process
            • -l long listing. Prints additional information about locks
            • -h or -help to print this help message
        • SA supported
          • jstack -F [-m] [-l] <pid> to connect to a hung process
          • jstack [-m] [-l] <executable> <core> to connect to a core file
          • jstack [-m] [-l] [server_id@]<remote server IP or hostname> to connect to a remote debug server
            • -F to force a thread dump. Use when jstack <pid> does not respond process is hung
            • -m to print both java and native frames (mixed mode)
      • SA's JStack实现分析
        • 官方文档对其实现机制有以下描述
          • SA consists mostly of Java classes but it contains a small amount of native code to read raw bits from processes and core files.
          • On Linux, SA uses a mix of /proc and ptrace (mostly the latter) to read bits from a process. For core files, SA parses ELF files directly.
        • 在Linux平台上,是使用了/proc和ptrace
        • 1.SA工具的基类是Tool,通过调用start方法启动,该方法里面会new一个BugSpotAgent,并且attach到目标VM上面
          - 先来看是怎么attach到目标进程的
          // attach to a process/thread specified by "pid"
          static bool ptrace_attach(pid_t pid) {
          if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {//这里调用了系统调用ptrace!!!
          print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
          return false;
          } else {
          return ptrace_waitpid(pid);
          }
          }
          - rslt = ptrace(PTRACE_PEEKDATA, ph->pid, aligned_addr, 0);//读取数据
          - 后面的太复杂,有兴趣的看看http://blog.csdn.net/kisimple/article/details/46496721
        • 总结一下,
          • 通过/proc/[pid]/maps读取ELF文件,保存符号表
          • 通过符号表读取HotSpotVM中localHotSpotVMStructs,localHotSpotVMTypes等变量的地址
          • 使用ptrace读取上述变量的值
          • 这两个变量值包含了SA需要用到的HotSpotVM中的数据的元信息(类型信息,字段offset,地址等)
          • 有了这些元信息就可以使用ptrace读取目标VM上这些数据的值
  • References


  • Java Attach Api 实现分析

    • The Attach API is a Sun Microsystems extension that provides a mechanism to attach to a Java™ virtual machine. A tool written in the Java Language, uses this API to attach to a target virtual machine and load its tool agent into that virtual machine. For example, a management console might have a management agent which it uses to obtain management information from instrumented objects in a virtual machine. If the management console is required to manage an application that is running in a virtual machine that does not include the management agent, then this API can be used to attach to the target virtual machine and load the agent.
  • References

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 易效能57:梦想与年度检视 指定年度规划,九宫格模式,每年底做年度检视,与预期的结果做对比,总结好的,再指定更长的...
    总在成长阅读 261评论 0 0
  • 盛夏但很凉爽的一个下午,我和女儿璇在家开心的嬉戏。 听到屋门打开,传来儿子兴高采烈...
    花儿家有喜事阅读 327评论 0 0
  • 最近读了几本书,每本书都不同的故事,都有不同的人生。在这个世界上,爱情似乎是最有魔力的和魅力的,拥有了爱情谁就可以...
    心若兮阅读 287评论 0 2