精华内容
下载资源
问答
  • backtrace

    千次阅读 2019-01-14 10:26:37
    backtrace代码里获取调用堆栈 介绍用法 [1] http://man7.org/linux/man-pages/man3/backtrace.3.html [2] https://www.gnu.org/software/libc/manual/html_node/Backtraces.html 代码 void PrintTrace() { ...

    backtrace代码里获取调用堆栈

    介绍用法

    [1] http://man7.org/linux/man-pages/man3/backtrace.3.html
    [2] https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
    [3] https://www.cnblogs.com/mickole/p/3246702.html

    代码

    void PrintTrace() {
        int nptrs;
        void *buffer[200]; 
        char **strings;
    
        nptrs = backtrace(buffer, 200);
        strings = backtrace_symbols(buffer, nptrs);
    
        if (strings != NULL) {
            for (int j = 0; j < nptrs; j ++) 
                LOG(INFO) << strings[j] << endl;
        }   
        LOG(INFO) << "PrintTrace" << endl;
        free(strings);
    }
    
    展开全文
  • backtrace-开源

    2021-07-25 19:17:32
    Backtrace 是 libexecinfo 和 glibc 的 backtrace API 的替代品。 由于 libexecinfo 在 OpenBSD 上不起作用,并且 glibc 的回溯是纯 linux goo,因此决定编写一个有效的替代品。
  • 主要介绍了php中debug_backtrace、debug_print_backtrace和匿名函数用法,以实例形式分析了debug_backtrace和debug_print_backtrace函数在调试过程中的作用,并分析了PHP5.3新增匿名函数的用法,需要的朋友可以参考下
  • backtrace.rar

    2020-06-13 13:25:10
    通过捕捉signal来打印对应的backtrace,需要注意的是执行档和所有lib必须添加-rdynamic -funwind-tables -ffunction-sections参数编译
  • backtracebacktrace_symbols函数原理解析

    千次阅读 2019-04-02 10:48:27
    backtrace()是glibc(>=2.1)提供的函数,用于跟踪函数的调用关系。 以下对backtrace()函数的说明以及实例,都来自其man page。 函数定义 #include <execinfo.h> int backtrace(void **buffer, int ...

    backtrace()是glibc(>=2.1)提供的函数,用于跟踪函数的调用关系。

    以下对backtrace()函数的说明以及实例,都来自其man page。


    函数定义
           #include <execinfo.h>

           int backtrace(void **buffer, int size);

           char **backtrace_symbols(void *const *buffer, int size);

           void backtrace_symbols_fd(void *const *buffer, int size, int fd);

    函数说明

    backtrace()函数用来获取程序中当前函数的回溯信息,即一系列的函数调用关系,获取到的信息被放在参数buffer中。buffer是一个数组指针,数组的每个元素保存着每一级被调用函数的返回地址。参数size指定了buffer中可存放的返回地址的数量。如果函数实际的回溯层级数大于size,则buffer中只能存放最近的函数调用关系,所以,想要得到完整的回溯信息,就要确保size参数足够大。
    backtrace()函数的返回值为buffer中的条目数量,这个值不一定等于size,因为如果为得到完整回溯信息而将size设置的足够大,则该函数的返回值为buffer中实际得到的返回地址数量。
     
    通过backtrace()函数得到buffer之后,backtrace_symbols()可以将其中的返回地址都对应到具体的函数名,参数size为buffer中的条目数。backtrace_symbols()函数可以将每一个返回值都翻译成“函数名+函数内偏移量+函数返回值”,这样就可以更直观的获得函数的调用关系。
    经过翻译后的函数回溯信息放到backtrace_symbols()的返回值中,如果失败则返回NULL。需要注意,返回值本身是在backtrace_symbols()函数内部进行malloc的,所以必须在后续显式地free掉。
     
    backtrace_symbols_fd()的buffer和size参数和backtrace_symbols()函数相同,只是它翻译后的函数回溯信息不是放到返回值中,而是一行一行的放到文件描述符fd对应的文件中。

    注意,在编译的时候需要加上-rdynamic选项让链接器将所有符号添加到动态符号表中,这样才能将函数地址翻译成函数名。另外,这个选项不会处理static函数,所以,static函数的符号无法得到。

    示例:
     

    #include <execinfo.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    void
    myfunc3(void)
    {
       int j, nptrs;
    #define SIZE 100
       void *buffer[100];
       char **strings;
     
       nptrs = backtrace(buffer, SIZE);
       printf("backtrace() returned %d addresses\n", nptrs);
     
       /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
    	  would produce similar output to the following: */
     
       strings = backtrace_symbols(buffer, nptrs);
       if (strings == NULL) {
    	   perror("backtrace_symbols");
    	   exit(EXIT_FAILURE);
       }
     
       for (j = 0; j < nptrs; j++)
    	   printf("%s\n", strings[j]);
     
       free(strings);
    }
     
    static void   /* "static" means don't export the symbol... */
    myfunc2(void)
    {
       myfunc3();
    }
     
    void
    myfunc(int ncalls)
    {
       if (ncalls > 1)
    	   myfunc(ncalls - 1);
       else
    	   myfunc2();
    }
     
    int
    main(int argc, char *argv[])
    {
       if (argc != 2) {
    	   fprintf(stderr, "%s num-calls\n", argv[0]);
    	   exit(EXIT_FAILURE);
       }
     
       myfunc(atoi(argv[1]));
       exit(EXIT_SUCCESS);
    }

    进行编译:

    cc -rdynamic prog.c -o prog
    代码运行结果为:

    $ ./prog 3
               backtrace() returned 8 addresses
               ./prog(myfunc3+0x5c) [0x80487f0]
               ./prog [0x8048871]
               ./prog(myfunc+0x21) [0x8048894]
               ./prog(myfunc+0x1a) [0x804888d]
               ./prog(myfunc+0x1a) [0x804888d]
               ./prog(main+0x65) [0x80488fb]
               /lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c]
               ./prog [0x8048711]
     

     

    采用信号量进行崩溃日志打印:

    #include <execinfo.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
     
    void trace(int signo)
    {
    	int j, nptrs;
    #define SIZE 100
    	void *buffer[100];
    	char **strings;
     
    	printf("signo: %d\n", signo);
     
    	nptrs = backtrace(buffer, SIZE);
    	printf("backtrace() returned %d addresses\n", nptrs);
     
    	/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
    	 *               would produce similar output to the following: */
     
    	strings = backtrace_symbols(buffer, nptrs);
    	if (strings == NULL) {
    		perror("backtrace_symbols");
    		exit(EXIT_FAILURE);
    	}
     
    	for (j = 0; j < nptrs; j++)
    		printf("%s\n", strings[j]);
     
    	free(strings);
     
    	if (SIGSEGV == signo || SIGQUIT == signo) {
    		exit(0);
    	}
    }
     
    void segfault(void)
    {
    	int *p = NULL;
    	*p = 1;
    }
     
    int main(int argc, char *argv[])
    {
    	signal(SIGSEGV, trace);
    	signal(SIGINT, trace);
    	signal(SIGQUIT, trace);
     
    	while (1) {
    		sleep(1);
    		if (time(0) % 7 == 0) {
    			segfault();
    		}
    	}
     
    	return 0;
    }

    编译方法  gcc -rdynamic seg.c -o seg -g


    段错信息


        signo: 11
        backtrace() returned 6 addresses
        ./seg(trace+0x3c) [0x400aac]
        /lib64/libc.so.6() [0x3c39635690]
        ./seg(segfault+0x10) [0x400b64]
        ./seg(main+0x83) [0x400bef]
        /lib64/libc.so.6(__libc_start_main+0xf5) [0x3c39621b45]
        ./seg() [0x4009a9]


    使用  objdump -d seg  查看出错地址  0x400b64  是一个赋值操作

        0000000000400b54 <segfault>:
          400b54:       55                      push   %rbp
          400b55:       48 89 e5                mov    %rsp,%rbp
          400b58:       48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
          400b5f:       00
          400b60:       48 8b 45 f8             mov    -0x8(%rbp),%rax
          400b64:       c7 00 01 00 00 00       movl   $0x1,(%rax)
          400b6a:       5d                      pop    %rbp
          400b6b:       c3                      retq   

     

    使用  addr2line 0x400b64 -e seg -afs  查看段错函数和对应的代码行数

        0x0000000000400b64
        segfault
        seg.c:41

    展开全文
  • 如何分析Android程序的backtrace最近碰到Android apk crash的问题,单从log很难定位。从tombstone里面得到下面的backtrace。*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***Build fingerprint: '...

    如何分析Android程序的backtrace

    最近碰到Android apk crash的问题,单从log很难定位。从tombstone里面得到下面的backtrace。

    *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

    Build fingerprint: 'Android/msm8996/msm8996:7.1.2/N2G47H/20180921.193127:userdebug/test-keys'

    Revision: '0'

    ABI: 'arm64'

    pid: 2848, tid: 3158, name: Thread-5819  >>> com.company.package <<<

    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0

    x0   0000007fa5ae0a60  x1   0000000000000000  x2   0000000000000008  x3   0000000000000010

    x4   0000000000000000  x5   c6a4a7935bd1e995  x6   c6a4a7935bd1e995  x7   0000000000000000

    x8   0000007fa5ae0ab8  x9   0000007f8d4e2ac8  x10  0000000000000174  x11  0000000000000000

    x12  0000007f8d4e2ac8  x13  ffffffffffffffff  x14  0000000000000000  x15  003b9aca00000000

    x16  0000007f98060850  x17  0000007fb69177c0  x18  0000000000000020  x19  0000007f97a12330

    x20  0000007f870feb68  x21  0000007f870feb40  x22  0000000000000000  x23  0000007f7ef07ac0

    x24  0000007f870fea78  x25  0000007f978c03a0  x26  0000007f870ff2f0  x27  0000007f870fea20

    x28  0000007f870feba0  x29  0000007f870fe6f0  x30  0000007f9725f6c8

    sp   0000007f870fe6f0  pc   0000007f9725f6c8  pstate 0000000080000000

    v0   00000000000000000000000000000000  v1   00000000000000000000000000000000

    v2   00000000000000000000000000000000  v3   00000000000000000000000000000000

    v4   00000000000000004000000000000000  v5   00000000000000000000000000000000

    v6   00000000000000000000000000000000  v7   00000000000000000000000000000000

    v8   0000000000000000000000003ce0e100  v9   00000000000000000000000042ff0000

    v10  0000000000000000000000003f800000  v11  00000000000000000000000000000000

    v12  00000000000000000000000000000000  v13  00000000000000000000000000000000

    v14  00000000000000000000000000000000  v15  00000000000000000000000000000000

    v16  000000000000000000000000c307e06a  v17  0000000000000000fffefffdfffdfffe

    v18  0000000000000000fffffffefffeffff  v19  000000000000000000ee00ee00ee00ee

    v20  000000000000000000040003fffdfffc  v21  000000000000000000ef00ef00ed00ec

    v22  00000002000000020000000200000002  v23  00000000000000000000000000000148

    v24  00000000000000000000000000000001  v25  00000000000000000000000000000029

    v26  0000000000000000000000003e800000  v27  000000000000000000000000bf737871

    v28  0000000000000000000000003f737871  v29  00000000000000000000007f8d52cf38

    v30  00000000000000000000000000000140  v31  000000000000000000000000bfc4f8c4

    fpsr 0000001b  fpcr 00000000

    backtrace:

    #00 pc 00000000000a96c8  /system/app/Package/Package.apk (offset 0x5c1000)

    #01 pc 00000000000b4574  /system/app/Package/Package.apk (offset 0x5c1000)

    #02 pc 00000000000d52f0  /system/app/Package/Package.apk (offset 0x5c1000)

    #03 pc 00000000000367ac  /system/app/Package/Package.apk (offset 0xe0e000)

    #04 pc 0000000000033070  /system/app/Package/Package.apk (offset 0xe0e000)

    #05 pc 0000000000176910  /system/app/Package/Package.apk (offset 0xe0e000)

    #06 pc 0000000000068618  /system/lib64/libc.so (_ZL15__pthread_startPv+196)

    #07 pc 000000000001df68  /system/lib64/libc.so (__start_thread+16)

    一看这个backtrace有点傻眼。通常得到的backtrace应该会打印出调用的so还有相应的函数名,这个不知道怎么回事只显示出apk的名字。调查了半天,怀疑是只有在apk是install的时候,才会有符号表的信息,出现有信息的打印。我们这个出现问题的时候,apk是编到rom里的,so库的符号表应该都被stip掉了。但是问题是这个crash很难重现,安装apk以后一直复现不了。好在这个apk自己只有三个so库,用addr2line试一试应该容易试出来。Android的sdk里自带了addr2line的工具,我们用的ndk13b版本,在windows上这个工具所在的目录是\Android\Sdk\android-ndk-r13b\toolchains\x86_64-4.9\prebuilt\windows-x86_64\bin,用-e参数指定文件名,-f参数显示函数名。果然,很容易就试出来是哪个so了。

    $ ./x86_64-linux-android-addr2line.exe -e ~/StudioProjects/Service/package/app/build/intermediates/cmake/debug/obj/arm64-v8a/libndk_camera.so -f 176910

    execute_native_thread_routine

    /usr/local/google/buildbot/src/android/ndk-r13-release/toolchain/gcc/gcc-4.9/libstdc++-v3/src/c++11/thread.cc:84

    $ ./x86_64-linux-android-addr2line.exe -e ~/StudioProjects/RobotVisionService/package/app/build/intermediates/cmake/debug/obj/arm64-v8a/libndk_camera.so -f 33070

    _ZNKSt7_Mem_fnIM12CameraEngineFvvEEclIJEvEEvPS0_DpOT_

    C:/Users/qwang/AppData/Local/Android/Sdk/android-ndk-r13b/sources/cxx-stl/gnu-libstdc++/4.9/include/functional:569 (discriminator 4)

    $ ./x86_64-linux-android-addr2line.exe -e ~/StudioProjects/RobotVisionService/package/app/build/intermediates/cmake/debug/obj/arm64-v8a/libndk_camera.so -f 367ac

    _ZN12CameraEngine12ProcessFrameEv

    C:\Users\qwang\StudioProjects\RobotVisionService\package\app\src\main\cpp/camera_engine.cpp:525 (discriminator 2)

    $ ./x86_64-linux-android-addr2line.exe -e ~/StudioProjects/RobotVisionService/package/app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so -f d52f0

    _ZN9OrionAlgo38vision_Algo_regressFacekeypointFromMatEN2cv3MatEiiii

    C:\Users\qwang\StudioProjects\RobotVisionService\package\app\src\main\cpp/OrionAlgo.cpp:107

    $ ./x86_64-linux-android-addr2line.exe -e ~/StudioProjects/RobotVisionService/package/app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so -f b4574

    _ZN6vision13TrackStrategy13trackOrDetectERN2cv3MatEPNS_3SSDERSt6vectorI3BoxSaIS7_EEf

    C:\Users\qwang\StudioProjects\RobotVisionService\package\app\src\main\cpp\src\main\cpp\inference\postproc\src/track_strategy.cpp:38

    $ ./x86_64-linux-android-addr2line.exe -e ~/StudioProjects/RobotVisionService/package/app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so -f a96c8

    _ZN6vision3SSD6detectERN2cv3MatERSt6vectorI3BoxSaIS5_EE

    C:\Users\qwang\StudioProjects\RobotVisionService\package\app\src\main\cpp\src\main\cpp\inference\algo\src/ssd.cpp:82

    展开全文
  • Backtrace 分析

    千次阅读 2018-06-25 19:36:48
    Java Backtrace从Java Backtrace, 我们可以知道当时Process 的虚拟机执行状态. Java Backtrace 依靠SignalCatcher 来抓取.Google default: SignalCatcher catchs SIGQUIT(3), and then print the java backtrace to...
    
    1. Java Backtrace
    从Java Backtrace, 我们可以知道当时Process 的虚拟机执行状态. Java Backtrace 依靠SignalCatcher 来抓取.
    Google default: SignalCatcher catchs SIGQUIT(3), and then print the java backtrace to /data/anr/trace.txt
    MTK Enhance:  SignalCatcher catchs SIGSTKFLT(16), and then print the java backtrace to /data/anr/mtktrace.txt( After 6577.SP/ICS2.MP)
    You can update system properties dalvik.vm.stack-trace-file to  Change the address,  default is /data/anr/traces.txt
     
    1.1 抓取的方式
    * 在ENG Build 中
    adb remount
    adb shell chmod 0777 data/anr
    adb shell kill -3 pid
    adb pull /data/anr
     
    * 在User Build 中
    没有root 权限的情况下,只能直接pull 已经存在的backtrace.
    adb pull /data/anr
     
    * 你可以尝试直接使用下面的脚本一次性抓取

    adb remount
    adb shell chmod 0777 data/anr
    adb shell ps
    @echo off
    set processid=
    set /p processid=Please Input process id:
    @echo on
    adb shell kill -3 %processid%
    @echo off
    ping -n 8 127.0.0.1>nul
    @echo on
    adb pull data/anr/traces.txt trace-%processid%.txt
    pause
     
    1.2 JavaBacktrace 解析
    下面是一小段system server 的java backtrace 的开始
    ----- pid 682 at 2014-07-30 18:04:53 -----
    Cmd line: system_server
    JNI: CheckJNI is off; workarounds are off; pins=4; globals=1484 (plus 50 weak)
    DALVIK THREADS:
    (mutexes: tll=0 tsl=0 tscl=0 ghl=0)
    "main" prio=5 tid=1 NATIVE
      | group="main" sCount=1 dsCount=0 obj=0x4193fde0 self=0x418538f8
      | sysTid=682 nice=-2 sched=0/0 cgrp=apps handle=1074835940
      | state=S schedstat=( 47858718206 26265263191 44902 ) utm=4074 stm=711 core=0
      at android.os.MessageQueue.nativePollOnce(Native Method)
      at android.os.MessageQueue.next(MessageQueue.java:138)
      at android.os.Looper.loop(Looper.java:150)
      at com.android.server.ServerThread.initAndLoop(SystemServer.java:1468)
      at com.android.server.SystemServer.main(SystemServer.java:1563)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
      at dalvik.system.NativeStart.main(Native Method)
       
    我们一行一行来解析.
    * 0# 最开始是 -----PID at Time  然后接着 Cmd line: process name
     
    * 1#  the backtrace header: dvm thread :“DALVIK THREADS:”
     
    * 2#  Global DVM mutex value: if 0 unlock,  else lock
     tll:  threadListLock,  
     tsl:  threadSuspendLock,  
     tscl: threadSuspendCountLock
     ghl:  gcHeapLock
     
     (mutexes: tll=0 tsl=0 tscl=0 ghl=0)
     
    * 3# thread name, java thread Priority, [daemon], DVM thread id, DVM thread status.
     "main"  -> main thread -> activity thread
     prio  -> java thread priority default is 5, (nice =0, linux thread priority 120),  domain is [1,10]
     DVM thread id, NOT linux thread id
     DVM thread Status:
      ZOMBIE,  RUNNABLE, TIMED_WAIT, MONITOR, WAIT, INITALIZING,STARTING, NATIVE, VMWAIT, SUSPENDED,UNKNOWN
     
     "main" prio=5 tid=1 NATIVE
     
    * 4# DVM thread status  
     group: default is “main”
       Compiler,JDWP,Signal Catcher,GC,FinalizerWatchdogDaemon,FinalizerDaemon,ReferenceQueueDaemon are system group
     sCount:  thread suspend count
     dsCount: thread dbg suspend count
     obj:     thread obj address
     Sef:  thread point address
     
     group="main" sCount=1 dsCount=0 obj=0x4193fde0 self=0x418538f8
     
    * #5 Linux thread status
     sysTId:  linux thread tid
     Nice: linux thread nice value
     sched: cgroup policy/gourp id
     cgrp:  c group  
     handle:  handle address
     sysTid=682 nice=-2 sched=0/0 cgrp=apps handle=1074835940
     
    * #6 CPU Sched stat
     Schedstat (Run CPU Clock/ns, Wait CPU Clock/ns,  Slice times)
     utm: utime, user space time(jiffies)
     stm: stime, kernel space time(jiffies)
     Core now running in cpu.
     state=S schedstat=( 47858718206 26265263191 44902 ) utm=4074 stm=711 core=0
     
    * #7-more Call Stack
     
    1.3 几种常见的java backtrace
     
    1.3.1 ActivityThread 正常状态/ActivityThread Normal Case

    Message Queue is empty, and thread wait for next message.
     "main" prio=5 tid=1 NATIVE
       | group="main" sCount=1 dsCount=0 obj=0x4193fde0 self=0x418538f8
       | sysTid=11559 nice=0 sched=0/0 cgrp=apps/bg_non_interactive handle=1074835940
       | state=S schedstat=( 2397315020 9177261498 7975 ) utm=100 stm=139 core=1
       at android.os.MessageQueue.nativePollOnce(Native Method)
       at android.os.MessageQueue.next(MessageQueue.java:138)
       at android.os.Looper.loop(Looper.java:150)
       at android.app.ActivityThread.main(ActivityThread.java:5299)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
       at dalvik.system.NativeStart.main(Native Method)
       
    1.3.2 Java Backtrace Monitor case

    Synchronized Lock: 等待同步锁时的backtrace.
     "AnrMonitorThread" prio=5 tid=24 MONITOR
       | group="main" sCount=1 dsCount=0 obj=0x41fd80c8 self=0x551ac808
       | sysTid=711 nice=0 sched=0/0 cgrp=apps handle=1356369328
       | state=S schedstat=( 8265377638 4744771625 6892 ) utm=160 stm=666 core=0
       at com.android.server.am.ANRManager$AnrDumpMgr.dumpAnrDebugInfoLocked(SourceFile:~832)
       - waiting to lock <0x42838968> (a com.android.server.am.ANRManager$AnrDumpRecord) held by tid=20 (ActivityManager)
       at com.android.server.am.ANRManager$AnrDumpMgr.dumpAnrDebugInfo(SourceFile:824)
       at com.android.server.am.ANRManager$AnrMonitorHandler.handleMessage(SourceFile:220)
       at android.os.Handler.dispatchMessage(Handler.java:110)
       at android.os.Looper.loop(Looper.java:193)
       at android.os.HandlerThread.run(HandlerThread.java:61)
        
    1.3.3 执行JNI code 未返回,状态是native 的情况

     "WifiP2pService" prio=5 tid=37 NATIVE
       | group="main" sCount=1 dsCount=0 obj=0x427a9910 self=0x55f088d8
       | sysTid=734 nice=0 sched=0/0 cgrp=apps handle=1443230288
       | state=S schedstat=( 91121772 135245305 170 ) utm=7 stm=2 core=1
       #00  pc 00032700  /system/lib/libc.so (epoll_wait+12)
       #01  pc 000105e3  /system/lib/libutils.so (android::Looper::pollInner(int)+94)
       #02  pc 00010811  /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+92)
       #03  pc 0006c96d  /system/lib/libandroid_runtime.so (android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+22)
       #04  pc 0001eacc  /system/lib/libdvm.so (dvmPlatformInvoke+112)
       #05  pc 0004fed9  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)
       #06  pc 00027ea8  /system/lib/libdvm.so
       #07  pc 0002f4b0  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
       #08  pc 0002c994  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+188)
       #09  pc 000632a5  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+340)
       #10  pc 000632c9  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
       #11  pc 00057961  /system/lib/libdvm.so
       #12  pc 0000dd40  /system/lib/libc.so (__thread_entry+72)
       at android.os.MessageQueue.nativePollOnce(Native Method)
       at android.os.MessageQueue.next(MessageQueue.java:138)
       at android.os.Looper.loop(Looper.java:150)
       at android.os.HandlerThread.run(HandlerThread.java:61)
        
    1.3.4 执行object.wait 等待状态

     "AsyncTask #1" prio=5 tid=33 WAIT
       | group="main" sCount=1 dsCount=0 obj=0x427a8480 self=0x56036b40
       | sysTid=733 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1443076000
       | state=S schedstat=( 1941480839 10140523154 4229 ) utm=119 stm=75 core=0
       at java.lang.Object.wait(Native Method)
       - waiting on <0x427a8618> (a java.lang.VMThread) held by tid=33 (AsyncTask #1)
       at java.lang.Thread.parkFor(Thread.java:1212)
       at sun.misc.Unsafe.park(Unsafe.java:325)
       at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
       at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2017)
       at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
       at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:848)
     
    1.3.5 Suspend 状态,通常表明是抓取backtrace 时,当时还正在执行java code, 被强制suspend 的情况
     "FileObserver" prio=5 tid=23 SUSPENDED
       | group="main" sCount=1 dsCount=0 obj=0x41fd1dc8 self=0x551abda0
       | sysTid=710 nice=0 sched=0/0 cgrp=apps handle=1427817920
       | state=S schedstat=( 130152222 399783851 383 ) utm=9 stm=4 core=0
       #00  pc 000329f8  /system/lib/libc.so (__futex_syscall3+8)
       #01  pc 000108cc  /system/lib/libc.so (__pthread_cond_timedwait_relative+48)
       #02  pc 0001092c  /system/lib/libc.so (__pthread_cond_timedwait+64)
       #03  pc 00055a93  /system/lib/libdvm.so
       #04  pc 0005614d  /system/lib/libdvm.so (dvmChangeStatus(Thread*, ThreadStatus)+34)
       #05  pc 0004ae7f  /system/lib/libdvm.so
       #06  pc 0004e353  /system/lib/libdvm.so
       #07  pc 000518d5  /system/lib/libandroid_runtime.so
       #08  pc 0008af9f  /system/lib/libandroid_runtime.so
       #09  pc 0001eacc  /system/lib/libdvm.so (dvmPlatformInvoke+112)
       #10  pc 0004fed9  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)
       #11  pc 00027ea8  /system/lib/libdvm.so
       #12  pc 0002f4b0  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
       #13  pc 0002c994  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+188)
       #14  pc 000632a5  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+340)
       #15  pc 000632c9  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
       #16  pc 00057961  /system/lib/libdvm.so
       #17  pc 0000dd40  /system/lib/libc.so (__thread_entry+72)
       at android.os.FileObserver$ObserverThread.observe(Native Method)
       at android.os.FileObserver$ObserverThread.run(FileObserver.java:88)
     
    2. Native Backtrace
     
    2.1 Native Backtrace 抓取方式
     
    2.1.1 利用debuggerd 抓取
    MTK 已经制作了一个利用debuggerd 抓取Native backtrace 的tool RTT(Runtime Trace), 对应的执行命令是:
    rtt built timestamp (Apr 18 2014 15:36:21)
    USAGE : rtt [-h] -f function -p pid [-t tid]
      -f funcion : current support functions:
                     bt  (Backtrace function)
      -p pid     : pid to trace
      -t tid     : tid to trace
      -n name    : process name to trace
      -h         : help menu
       
    2.1.2 添加代码直接抓取
    Google 默认提供了CallStack API, 请参考
    system/core/include/libutils/CallStack.h  
    system/core/libutils/CallStack.cpp
    可快速打印单个线程的backtrace.
     
    2.2 解析Native Backtrace
    你可以使用GDB, 或者addr2line 等 tool 来解析抓回的Native Backtrace, 从而知道当时正在执行的native 代码.
    如addr2line 执行
    arm-linux-androideabi-addr2line -f -C -e symbols address
     
    3. Kernel Backtrace
     
    3.1 Kernel Backtrace 抓取方式
     
    3.1.1 运行时抓取
    * AEE/RTT 工具

     
    * Proc System
      cat proc/pid/task/tid/stack

     
    * Sysrq-trigger
     adb shell cat proc/kmsg > kmsg.txt
     adb shell "echo 8 > proc/sys/kernel/printk“ //修改printk loglevel
     adb shell "echo t > /proc/sysrq-trigger“ //打印所有的backtrace
     adb shell "echo w > /proc/sysrq-trigger“//打印'-D' status 'D' 的 process
     
    * KDB
     Long press volume UP and DOWN more then 10s
     btp             <pid>                 
     Display stack for process <pid>
     bta             [DRSTCZEUIMA]         
     Display stack all processes
     btc                                   
     Backtrace current process on each cpu
     btt             <vaddr>               
     Backtrace process given its struct task add
     
    3.1.2 添加代码直接抓取
    * #include <linux/sched.h>
     当前thread:  dump_stack();
     其他thread:  show_stack(task, NULL);
     
    3.2 Process/Thread 状态
     "R (running)",  /*   0 */
     "S (sleeping)",  /*   1 */
     "D (disk sleep)", /*   2 */
     "T (stopped)",  /*   4 */
     "t (tracing stop)", /*   8 */
     "Z (zombie)",  /*  16 */
     "X (dead)",  /*  32 */
     "x (dead)",  /*  64 */
     "K (wakekill)",  /* 128 */
     "W (waking)",  /* 256 */
     
    通常一般的Process 处于的状态都是S (sleeping), 而如果一旦发现处于如D (disk sleep), T (stopped), Z (zombie) 等就要认真审查.
     
    4. 几种典型的异常情况

    4.1 Deadlock
    下面这个case 可以看到PowerManagerService, ActivityManager, WindowManager 相互之间发生deadlock.
    "PowerManagerService" prio=5 tid=25 MONITOR
      | group="main" sCount=1 dsCount=0 obj=0x42bae270 self=0x6525d5c0
      | sysTid=913 nice=0 sched=0/0 cgrp=apps handle=1696964440
      | state=S schedstat=( 5088939411 10237027338 34016 ) utm=232 stm=276 core=2
      at com.android.server.am.ActivityManagerService.bindService(ActivityManagerService.java:~14079)
      - waiting to lock <0x42aa0f78> (a com.android.server.am.ActivityManagerService) held by tid=16 (ActivityManager)
      at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1665)
      at android.app.ContextImpl.bindService(ContextImpl.java:1648)
      at com.android.server.power.PowerManagerService.bindSmartStandByService(PowerManagerService.java:4090)
      at com.android.server.power.PowerManagerService.handleSmartStandBySettingChangedLocked(PowerManagerService.java:4144)
      at com.android.server.power.PowerManagerService.access$5600(PowerManagerService.java:102)
      at com.android.server.power.PowerManagerService$SmartStandBySettingObserver.onChange(PowerManagerService.java:4132)
      at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:181)
      at android.os.Handler.handleCallback(Handler.java:809)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:139)
      at android.os.HandlerThread.run(HandlerThread.java:58)
       
      "ActivityManager" prio=5 tid=16 MONITOR
      | group="main" sCount=1 dsCount=0 obj=0x42aa0d08 self=0x649166b0
      | sysTid=902 nice=-2 sched=0/0 cgrp=apps handle=1687251744
      | state=S schedstat=( 39360881460 25703061063 69675 ) utm=1544 stm=2392 core=2
      at com.android.server.wm.WindowManagerService.setAppVisibility(WindowManagerService.java:~4783)
      - waiting to lock <0x42d17590> (a java.util.HashMap) held by tid=12 (WindowManager)
      at com.android.server.am.ActivityStack.stopActivityLocked(ActivityStack.java:2432)
      at com.android.server.am.ActivityStackSupervisor.activityIdleInternalLocked(ActivityStackSupervisor.java:2103)
      at com.android.server.am.ActivityStackSupervisor$ActivityStackSupervisorHandler.activityIdleInternal(ActivityStackSupervisor.java:2914)
      at com.android.server.am.ActivityStackSupervisor$ActivityStackSupervisorHandler.handleMessage(ActivityStackSupervisor.java:2921)
      at android.os.Handler.dispatchMessage(Handler.java:110)
      at android.os.Looper.loop(Looper.java:147)
      at com.android.server.am.ActivityManagerService$AThread.run(ActivityManagerService.java:2112)
       
      "WindowManager" prio=5 tid=12 MONITOR
      | group="main" sCount=1 dsCount=0 obj=0x42a92550 self=0x6491dd48
      | sysTid=898 nice=-4 sched=0/0 cgrp=apps handle=1687201104
      | state=S schedstat=( 60734070955 41987172579 219755 ) utm=4659 stm=1414 core=1
      at com.android.server.power.PowerManagerService.setScreenBrightnessOverrideFromWindowManagerInternal(PowerManagerService.java:~3207)
      - waiting to lock <0x42a95140> (a java.lang.Object) held by tid=25 (PowerManagerService)
      at com.android.server.power.PowerManagerService.setScreenBrightnessOverrideFromWindowManager(PowerManagerService.java:3196)
      at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedInner(WindowManagerService.java:9686)
      at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedLoop(WindowManagerService.java:8923)
      at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLocked(WindowManagerService.java:8879)
      at com.android.server.wm.WindowManagerService.access$500(WindowManagerService.java:170)
      at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:7795)
      at android.os.Handler.dispatchMessage(Handler.java:110)
      at android.os.Looper.loop(Looper.java:147)
      at android.os.HandlerThread.run(HandlerThread.java:58)
     
     
    4.2 执行JNI native code 后一去不复返
    "main" prio=5 tid=1 NATIVE
      | group="main" sCount=1 dsCount=0 obj=0x41bb3d98 self=0x41ba2878
      | sysTid=814 nice=-2 sched=0/0 cgrp=apps handle=1074389380
      | state=D schedstat=( 22048890928 19526803112 32612 ) utm=1670 stm=534 core=0
      (native backtrace unavailable)
      at android.hardware.SystemSensorManager$BaseEventQueue.nativeDisableSensor(Native Method)
      at android.hardware.SystemSensorManager$BaseEventQueue.disableSensor(SystemSensorManager.java:399)
      at android.hardware.SystemSensorManager$BaseEventQueue.removeAllSensors(SystemSensorManager.java:325)
      at android.hardware.SystemSensorManager.unregisterListenerImpl(SystemSensorManager.java:194)
      at android.hardware.SensorManager.unregisterListener(SensorManager.java:560)
      at com.android.internal.policy.impl.WindowOrientationListener.disable(WindowOrientationListener.java:139)
      at com.android.internal.policy.impl.PhoneWindowManager.updateOrientationListenerLp(PhoneWindowManager.java:774)
      at com.android.internal.policy.impl.PhoneWindowManager.screenTurnedOff(PhoneWindowManager.java:4897)
      at com.android.server.power.Notifier.sendGoToSleepBroadcast(Notifier.java:518)
      at com.android.server.power.Notifier.sendNextBroadcast(Notifier.java:434)
      at com.android.server.power.Notifier.access$500(Notifier.java:63)
      at com.android.server.power.Notifier$NotifierHandler.handleMessage(Notifier.java:584)
      at android.os.Handler.dispatchMessage(Handler.java:110)
      at android.os.Looper.loop(Looper.java:193)
      at com.android.server.ServerThread.initAndLoop(SystemServer.java:1436)
      at com.android.server.SystemServer.main(SystemServer.java:1531)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
      at dalvik.system.NativeStart.main(Native Method)
       
    ===>
    KERNEL SPACE BACKTRACE, sysTid=814
     [<ffffffff>] 0xffffffff from [<c07e5140>] __schedule+0x3fc/0x950
     [<c07e4d50>] __schedule+0xc/0x950 from [<c07e57e4>] schedule+0x40/0x80
     [<c07e57b0>] schedule+0xc/0x80 from [<c07e5ae4>] schedule_preempt_disabled+0x20/0x2c
     [<c07e5ad0>] schedule_preempt_disabled+0xc/0x2c from [<c07e3c3c>] mutex_lock_nested+0x1b8/0x560
     [<c07e3a90>] mutex_lock_nested+0xc/0x560 from [<c05667d8>] gsensor_operate+0x1bc/0x2c0
     [<c0566628>] gsensor_operate+0xc/0x2c0 from [<c0495fa0>] hwmsen_enable+0xa8/0x30c
     [<c0495f04>] hwmsen_enable+0xc/0x30c from [<c0496500>] hwmsen_unlocked_ioctl+0x2fc/0x528
     [<c0496210>] hwmsen_unlocked_ioctl+0xc/0x528 from [<c018ad98>] do_vfs_ioctl+0x94/0x5bc
     [<c018ad10>] do_vfs_ioctl+0xc/0x5bc from [<c018b33c>] sys_ioctl+0x7c/0x8c
     [<c018b2cc>] sys_ioctl+0xc/0x8c from [<c000e480>] ret_fast_syscall+0x0/0x40
     [<ffffffff>]  from [<ffffffff>]
    展开全文
  • backtrace backtrace_symbols

    2014-04-15 16:23:49
    调试打印函数名字 http://stackoverflow.com/questions/6934659/how-to-make-backtrace-backtrace-symbols-print-the-function-names
  • php-backtrace-源码

    2021-05-13 02:11:35
    PHP的回溯 Backtrace PHP扩展
  • MiniBacktrace 允许您在使用 MiniTest 时利用 Rails.backtrace_cleaner。 这包括使用 Rails 3 和 Ruby 1.9 的所有人。 用法 只需将 'mini_backtrace' 添加到您的 Gemfile 的 :test 组中,您应该会自动看到巨大的...
  • android backtrace实现

    2021-09-15 09:11:56
    backtrace 简介 有的系统没有实现backtrace这个函数. 常见的就有linux还有一些docker的库. 判断是否支持backtrace #include<stdio.h> #include<dlfcn.h> int main() { void * bt = dlsym...
  • Stack backtrace

    千次阅读 2015-09-18 16:04:33
    Stack backtrace 的实现 Stack backtrace栈回溯是指程序运行时打印出当前的调用栈。在程序调试、 运行异常时栈回溯显得非常有用。那栈回溯是如何实现的呢? 栈回溯的实现依赖编译器的特性,与特定的平台相关。以...
  • backtrace函数

    2019-04-10 22:00:00
    int backtrace(void **buffer, int size);  该函数获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针数组,参数size用来指定buffer中可以保存多少个void*元素。函数的返回值是实际返回的...
  • 参考: http://www.th7.cn/Program/cp/201308/145700.shtml http://linux.die.net/man/3/backtrace http://man7.org/linux/man-pages/man3/backtrace.3.html
  • backtrace execinfo.h

    千次阅读 2019-10-11 11:26:02
    http://man7.org/linux/man-pages/man3/backtrace.3.html BACKTRACE(3) linux编程者手册 BACKTRACE(3) 名称 top backtrace, backtrace_symbols, backtrace_symbols_fd - ...
  • 一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序...int backtrace(void **buffer,int size)  该函数用于获取当前线程的调用堆栈,获...
  • #ifndef __CRTL_BITS_ASSERT_H #define __CRTL_BITS_ASSERT_H 1 #include <errno.h> #include <...#include "crtl/bits/crtl_assert_backtrace.h" #define CRTL_SYS_ERROR strerror(errn...
  • backtrace 实现原理

    2019-11-26 21:41:16
    显示函数调用关系(backtrace/callstack)是调试器必备的功能之一,比如在gdb里,用bt命令就可以查看backtrace。在程序崩溃的时候,函数调用关系有助于快速定位问题的根源,了解它的实现原理,可以扩充自己的知识面,...
  • Android Apk跑native层代码挂死,日志如下:12-11 20:13:47.321 I/DEBUG ( 1491): backtrace:12-11 20:13:47.321 I/DEBUG ( 1491): #00 pc 00100696 /data/app-lib/...
  • Backtrace in Android

    2019-09-13 19:07:58
    libscorkscrew.so在android 5.0之后已经没有了,之前追踪backtrace的方法已经: #define MAX_DEPTH 31 #define MAX_BACKTRACE_LINE_LENGTH 800 #defi...
  • 通过backtrace()函数可以获得当前的程序堆栈地址. 提供一个指针数组, backtrace()函数会把调用堆栈的地址填到里面. #include int backtrace(void **buffer, int size); 为了跟踪动态库, 需要给gcc添加-...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,705
精华内容 10,282
关键字:

backtrace