android调用堆栈汇总

简介

下面列出的打印函数调用堆栈的方法,只会输出CallStack的信息,并不会抛出异常,也不会导致程序崩溃。

在很多情况下,我们无法通过gdb或DDD来单步调试应用,所以打印函数调用堆栈对于我们学习Android源码还是很有必要的(比如说:了解众多子类中,到底走的是哪个子类实例)。

Java代码
1
2
3
RuntimeException here =  new  RuntimeException( "here" );                                                                                               
here.fillInStackTrace();
Log.e(TAG,  "call stack: " , here);

C++代码

(For Android)

1
2
3
4
5
6
7
8
9
10
11
12
13
1.1
#include <utils/CallStack.h>               // 全路径[frameworks/base/include/utils/CallStack.h]
 
1.2
status_t AudioFlinger::setStreamVolume( int  stream,  float  value,  int  output)
{
     CallStack callstack;
     callstack.update();
     //callstack.dump(fd);
     callstack. log ( "log_tag" );
 
     // ... ...
}

C++代码

(Android不可用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
注:
因为Android中只添加了部分GCC,
但<execinfo.h>却没有添加到Android中,所以这个方法不能应用到Android的C/C++代码中。
 
 
/**
* =====================================================================================
*
*       Filename:  test_dump_C_CallStack.cpp
*
*    Description:  test dump C/C++ CallStack.
*   ------------------------------------------------------
*    编译方法,注意编译时带有“-rdynamic”参数,否则显示结果不正确:
*    [flobert@flobert-Lenovo:/media/D/my_projects/C++_projects/C++_test$]
*    <OP_CODE>:g++ -rdynamic -o test_dump_C_CallStack test_dump_C_CallStack.cpp
*    [flobert@flobert-Lenovo:/media/D/my_projects/C++_projects/C++_test$]
*    <OP_CODE>:./test_dump_C_CallStack 3
*    backtrace() returned 8 addresses
*    ./test_dump_C_CallStack(_Z7myfunc3v+0x1f) [0x8048863]
*    ./test_dump_C_CallStack() [0x80488f4]
*    ./test_dump_C_CallStack(_Z6myfunci+0x21) [0x8048917]
*    ./test_dump_C_CallStack(_Z6myfunci+0x1a) [0x8048910]
*    ./test_dump_C_CallStack(_Z6myfunci+0x1a) [0x8048910]
*    ./test_dump_C_CallStack(main+0x51) [0x804896a]
*    /lib/libc.so.6(__libc_start_main+0xe7) [0x441ce7]
*    ./test_dump_C_CallStack() [0x80487b1]
*    [flobert@flobert-Lenovo:/media/D/my_projects/C++_projects/C++_test$]
*    <OP_CODE>:c++filt _Z7myfunc3v
*    myfunc3()
*    [flobert@flobert-Lenovo:/media/D/my_projects/C++_projects/C++_test$]
*    <OP_CODE>:c++filt _Z6myfunci
*    myfunc(int)
*   ------------------------------------------------------
*
*        Version:  1.0
*        Created:  10/12/2011 06:05:44 PM
*       Revision:  none
*       Compiler:  gcc
*
*      Author:  yangzhl@lenovomobile.com
*
* =====================================================================================
*/
#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" means don't export the symbol... */
static  void  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);
}
Kernel Backtrace
1
2
3
#include <linux/sched.h>
当前 thread :  dump_stack();
其他 thread :  show_stack(task, NULL);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值