android调用堆栈汇总

本文介绍了一种在Android环境中打印函数调用堆栈的方法,适用于无法使用gdb或DDD进行单步调试的情况。文中提供了Java及特定条件下可用的C/C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

下面列出的打印函数调用堆栈的方法,只会输出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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值