Print call stack Needless to say, basically every developer will use, discuss a few methods, previously said, http://blog.csdn.net/freshui/article/details/9456889 again simple tidy up, wordy on the long-winded:)
Basically divided into two categories, one is static, to insert the printed statement into the code, a class is dynamic, need to look at the time to see, real-time observation of the thread call stack situation. Static methods
1. Print the call stack in Java
Relatively simple, using Throwable, direct log print out:
[Java]View PlainCopy
- LOG.D (TAG, log.getstacktracestring (new Throwable ()));
2. C + + Print Call stack is also relatively simple, direct use of the CallStack class
[CPP]View PlainCopy
- #include <utils/CallStack.h>
- ...
- CallStack stack ("fuck");
- ...
callstack from 4.3, rewrite the next, now the use is relatively simple, the instantiation of the place directly printed. 3. C in the print call stack
Previously written methods are complex and difficult to use (version updates, many libraries and interfaces have changed). In fact, it is super simple to print the call stack in C. Just find a source file of C + +, implement a function can be:
[CPP]View PlainCopy
- #include <utils/CallStack.h>
- extern "C" void Printcallstack ();
- void Printcallstack () {
- CallStack Stk ("fuck");
- }
This can be added to the Android existing code, or you can add a new CPP file to be compiled in. Where you want to print, call directly:
[CPP]View PlainCopy
- ...
- extern void Printcallstack ();
- void Test_c_code () {
- ...
- Printcallstack ();
- ...
- }
- ...
Attention:
- C + + code Printcallstack declaration must have extern "C", otherwise C + + mangle after the symbol, C is not recognized
- Note the link to the library after you add it, and the namespace is not mistaken.
In addition, the above method is actually applicable in the compilation of printing callstack, all the same ~ ~
The above CallStack method, the NDK is not good, and the old version may have compatibility issues, the NDK would like to use, need to deal with, but do not guarantee that every one of the same is done (in theory, Google is not unified, may not be insurance), the application package in the case, it is estimated to be careful.
4. Print the call stack in kernel-state code
The kernel look at the call stack, is also relatively simple, directly in the place to see, to join:
[HTML]View PlainCopy
- WARN_ON (1);
Problems with static printing:
- Static print call stack, need to modify code, recompile run
- For the underlying function, or a number of calls to the function, there will be a huge number of rogue log, can not be really analyzed.
Workaround, change the code this can't solve, for rogue log, you can think of some ways:
- CallStack Place, conditional trigger, set conditional trigger based on context
- Not good the above conditions, you can set the trigger conditions according to the process name/uid, etc.
- You can use the big trick: You define the property set conditions, you can change the shell serial port by changing the property value to toggle log switch.
Dynamic methods
Dynamic, in fact, the ADB even after the DDMS, the view is more convenient, the Java stack looks particularly handy, here are only a few ways to see the shell command:
1. Dump Java Call stack
The Java call stack actually contains native stacks and kernel stacks, all of which are more visible. The way to use it is simple:
[HTML]View PlainCopy
- Kill-3 <pid>
Because it is a virtual machine, it is currently available only for virtual machine processes (i.e. Java processes)
2. Dump Native Stack
It is easy to get native stack information with Debuggerd, which can be sampled or analyzed for stuck or deadlock problems.
[HTML]View PlainCopy
- Debuggerd-b <pid>
Note that this is not the Java call stack for the Java process, but the virtual machine call stack when the virtual machine executes Java instructions is required for the debugger virtual machine.
3. View the kernel stack
More difficult, most of the system is not open, see, but the debug version can be.
The way to see this is:
[HTML]View PlainCopy
- cat/proc/<pid>/task/<tid>/stack
However, the latest naugot on the call stack, it seems the latest do not do Demangle:
[HTML]View PlainCopy
- "Main" prio=5 tid=1 Native
- | group="main" scount=1 dscount=0 obj=0x748ef6b8 self=0xa638b400
- | systid=1774 nice=0 cgrp=default sched=0/0 handle= 0xaa74b534
- | state=S schedstat= (0 0 0) utm= stm=193 core= 0 hz= c19>
- | stack=0xbf403000-0xbf405000 stacksize=8MB
- | Held mutexes=
- kernel:sys_epoll_wait+0x23c/0x2d1
- Kernel:sys_epoll_pwait+0x70/0xe1
- kernel:sysenter_do_call+0x12/0x22
- Native: #00 pc ffffe424 [VDSO] (__KERNEL_VSYSCALL+16)
- Native: #01 pc 000779ab/system/lib/libc.so (__epoll_pwait+43)
- Native: #02 pc 00020cb0/system/lib/libc.so (epoll_pwait+112)
- Native: #03 pc 00020d0e/system/lib/libc.so (epoll_wait+62)
- Native: #04 pc 00018f1b/system/lib/libutils.so (_zn7android6looper9pollinnerei+203)
- Native: #05 pc 00018d84/system/lib/libutils.so (_zn7android6looper8pollonceeipis1_ppv+68)
- Native: #06 pc 000d38c3/system/lib/libandroid_runtime.so (_zn7android18nativemessagequeue8pollonceep7_jnienvp8_ jobjecti+77)
- Native: #07 pc 000d3934/system/lib/libandroid_runtime.so (???)
- Native: #08 pc 007b1c0c/system/framework/x86/boot-framework.oat (java_android_os_messagequeue_nativepollonce__ji+ 136)
- At Android.os.MessageQueue.nativePollOnce (Native method)
- At Android.os.MessageQueue.next (messagequeue.java:323)
- At Android.os.Looper.loop (looper.java:136)
- At Android.app.ActivityThread.main (activitythread.java:6119)
- At java.lang.reflect.method.invoke! (Native method)
- At Com.android.internal.os.zygoteinit$methodandargscaller.run (zygoteinit.java:886)
- At Com.android.internal.os.ZygoteInit.main (zygoteinit.java:776)
It's a bit of an egg ache, it's a bit uncomfortable to read, and it's about a bug that commits a record:
[HTML]View PlainCopy
- Commit 7c903fbacfaf449fb4f7a9fa2f1a1b6ba2db5330
- Author:josh Gao <[email protected]>
- Date:tue Mar 22 11:29:17 2016-0700
- Don ' t demangle symbol names.
- bug:http://b/27299236
- Change-id:i3a698c6d93e262fd78e743c1e6e946b054b9dcd1
Of course, these dynamic view of the call stack, through the ADB bugreport or dumpstate command, can be obtained. If there is a bug, you can save a copy of the bugreport, put it in the back to look slowly, and then to solve the scene analysis.
Android various ways to get code call stacks [complement]