-
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
- table
-
signal.h
- partial
-
define SIGQUIT 3
-
define SIGKILL 9
-
define SIGSTOP 19
-
- partial
-
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.
- SIGKILL
-
kill -l (kill -9 pid)
- SIGQUIT
- SIGKILL
- 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要跟蹤的進(jìn)程
void *addr, 指示要監(jiān)控的內(nèi)存地址
void *data);存放讀取出的或者要寫(xiě)入的數(shù)據(jù)- 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.)
- Attach to the process specified in pid, making it a tracee of
- ptrace(PTRACE_ATTACH, pid, 0, 0);
- PTRACE_ATTACH
- 你是否曾經(jīng)想過(guò)怎樣才能攔截系統(tǒng)調(diào)用?你是否曾經(jīng)想過(guò)通過(guò)修改一下系統(tǒng)調(diào)用的參數(shù)來(lái)耍一把內(nèi)核?你是否想過(guò)調(diào)試器是怎樣把一個(gè)進(jìn)程停下來(lái)槽奕,然后把控制權(quán)轉(zhuǎn)移給你的昼牛?如果你以為這些都是通過(guò)復(fù)雜的內(nèi)核編程來(lái)實(shí)現(xiàn)的,那你就錯(cuò)了臭觉,事實(shí)上考蕾,Linux 提供了一種很優(yōu)雅的方式來(lái)實(shí)現(xiàn)上述所有行為:ptrace 系統(tǒng)調(diào)用甩苛。ptrace 提供了一種機(jī)制使得父進(jìn)程可以觀察和控制子進(jìn)程的執(zhí)行過(guò)程,ptrace 還可以檢查和修改該子進(jìn)程的可執(zhí)行文件在內(nèi)存中的鏡像及該子進(jìn)程所使用的寄存器中的值赏参。這種用法通常來(lái)說(shuō)志笼,主要用于實(shí)現(xiàn)對(duì)進(jìn)程插入斷點(diǎn)和跟蹤子進(jìn)程的系統(tǒng)調(diào)用。
- ptrace函數(shù)可能會(huì)讓人們覺(jué)得很奇特把篓,因?yàn)樗尤豢梢詸z測(cè)和修改一個(gè)運(yùn)行中的程序纫溃。這種技術(shù)主要是在調(diào)試器和系統(tǒng)調(diào)用跟蹤程序中使用。它使程序員可以在用戶(hù)級(jí)別做更多有意思的事情韧掩。已經(jīng)有過(guò)很多在用戶(hù)級(jí)別下擴(kuò)展操作系統(tǒng)得嘗試紊浩,比如UFO,一個(gè)用戶(hù)級(jí)別的文件系統(tǒng)擴(kuò)展,它使用ptrace來(lái)實(shí)現(xiàn)一些安全機(jī)制疗锐。
- 進(jìn)程狀態(tài)TASK_TRACED用以表示當(dāng)前進(jìn)程因?yàn)楸桓高M(jìn)程跟蹤而被系統(tǒng)停止
- gdb是我們調(diào)試程序的利器,strace可以方便的幫助我們記錄進(jìn)程所執(zhí)行的系統(tǒng)調(diào)用 都是基于ptrace實(shí)現(xiàn)的;
-
References
-
proc
- process information pseudo-filesystem
- Linux 內(nèi)核提供了一種通過(guò) /proc 文件系統(tǒng)郎楼,在運(yùn)行時(shí)訪(fǎng)問(wèn)內(nèi)核內(nèi)部數(shù)據(jù)結(jié)構(gòu)、改變內(nèi)核設(shè)置的機(jī)制窒悔。
proc文件系統(tǒng)是一個(gè)偽文件系統(tǒng)呜袁,它只存在內(nèi)存當(dāng)中,而不占用外存空間简珠。
它以文件系統(tǒng)的方式為訪(fǎng)問(wèn)系統(tǒng)內(nèi)核數(shù)據(jù)的操作提供接口 - 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-daemon00652000-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阶界?簡(jiǎn)單來(lái)講SA就是HotSpot提供的一套JavaAPI,通過(guò)這套API我們可以獲取一個(gè)目標(biāo)JVM的運(yùn)行時(shí)信息聋庵,這套API的代碼在$JAVA_HOME/lib/sa-jdi.jar中膘融,源碼的話(huà)是在hotspot工程的agent目錄下: openjdk/hotspot/agent/***
- 介紹SA中的一個(gè)工具jstack。咦祭玉,jstack氧映,好眼熟,是的脱货,在JDK自帶的工具中也有一個(gè)jstack岛都,我們平時(shí)用的也都是它律姨。在SA中也有一個(gè)JStack,二者實(shí)現(xiàn)的機(jī)制完全不一樣
- JDK's JStack (openjdk/jdk/src/share/classes/sun/tools/jstack/JStack.java)
- 在jdk工程下發(fā)現(xiàn)了sun.tools.jstack.JStack臼疫,應(yīng)該就是jstack命令的源碼了择份。我們來(lái)跑下試下。這個(gè)類(lèi)是在$JAVA_HOME/lib/tools.jar中烫堤。先把環(huán)境變量配置好
- 2132是通過(guò)jps命令看到的另一個(gè)Java進(jìn)程的pid
- java sun.tools.jstack.JStack 2132
- 上面已經(jīng)說(shuō)到了兩個(gè)jstack實(shí)現(xiàn)的機(jī)制是完全不一樣的荣赶,SA中的jstack當(dāng)然是通過(guò)SA的機(jī)制實(shí)現(xiàn)的,那么JDK中的jstack又是通過(guò)什么機(jī)制呢鸽斟?其實(shí)是通過(guò)了另一個(gè)HotSpot提供的拔创,Dynamic Attach機(jī)制(跟SA二者都是HotSpot的私有機(jī)制,不是JVM標(biāo)準(zhǔn))富蓄,具體這個(gè)機(jī)制是怎么實(shí)現(xiàn)的剩燥,這里暫不展開(kāi),有興趣的同學(xué)可以看看笨神博客還有官方文檔格粪。
- SA's JStack (openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java)
- java sun.jvm.hotspot.tools.JStack 2132
- 看上去還是JDK自帶的jstack輸出友好一點(diǎn)躏吊。
- 加上-Dsun.jvm.hotspot.bugspot.BugSpotAgent.DEBUG=true選項(xiàng)會(huì)多輸出一行,SA's JVMDI帐萎,這個(gè)又是什么鬼比伏?暫不深究哈,還有SA的實(shí)現(xiàn)機(jī)制疆导,留待后續(xù)再作探討赁项。
- JDK's JStack實(shí)現(xiàn)分析
- 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(){//反射調(diào)用 // 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.
- 參數(shù)的值不能匹配數(shù)字[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
- jstack [-l] <pid> to connect to running process
- 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)
- 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
- SA's JStack實(shí)現(xiàn)分析
- 官方文檔對(duì)其實(shí)現(xiàn)機(jī)制有以下描述
- 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平臺(tái)上,是使用了/proc和ptrace
- 1.SA工具的基類(lèi)是Tool澈段,通過(guò)調(diào)用start方法啟動(dòng)悠菜,該方法里面會(huì)new一個(gè)BugSpotAgent,并且attach到目標(biāo)VM上面
- 先來(lái)看是怎么attach到目標(biāo)進(jìn)程的
// attach to a process/thread specified by "pid"
static bool ptrace_attach(pid_t pid) {
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {//這里調(diào)用了系統(tǒng)調(diào)用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);//讀取數(shù)據(jù)
- 后面的太復(fù)雜,有興趣的看看http://blog.csdn.net/kisimple/article/details/46496721 - 總結(jié)一下败富,
- 通過(guò)/proc/[pid]/maps讀取ELF文件悔醋,保存符號(hào)表
- 通過(guò)符號(hào)表讀取HotSpotVM中l(wèi)ocalHotSpotVMStructs,localHotSpotVMTypes等變量的地址
- 使用ptrace讀取上述變量的值
- 這兩個(gè)變量值包含了SA需要用到的HotSpotVM中的數(shù)據(jù)的元信息(類(lèi)型信息兽叮,字段offset芬骄,地址等)
- 有了這些元信息就可以使用ptrace讀取目標(biāo)VM上這些數(shù)據(jù)的值
- 官方文檔對(duì)其實(shí)現(xiàn)機(jī)制有以下描述
- JStack
-
References
-
Java Attach Api 實(shí)現(xiàn)分析
- 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