java 打印调用栈:

import android.util.Log;

Log.i(TAG, Log.getStackTraceString(new Throwable()));

c++,比如netd里

Android为方便Native层打印函数的调用堆栈,专门在system/core/libutils下设计了CallStack.cpp类
如果需要打印Native的stack只需要在自己的代码的mk文件中添加对libutils.so添加依赖,在类文件中include <utils/CallStack.h> 头文件。

实现方法如下:

.cpp文件
#include <utils/CallStack.h>

CallStack stack("powered by gaojian");
 

在编译文件添加对libutils.so的依赖,如下:

Android.mk
LOCAL_SHARED_LIBRARIES += libutils
 

该方案的缺点:

  1. 需要修改编译文件,有时候依赖libutils会不成功
  2. 只能在cpp文件中使用,无法在.c文件中使用

为解决该问题,本人百度、google研究了个遍,各种攻略都以失败告终,自己也相当郁闷,
难道就没有一个简单通用方法在c/c++文件中打印堆栈吗?
答案是肯定的

自己去研究了下CallStack .cpp,突发灵感,只要稍微对CallStack .cpp做修改,即可搞定这个问题!!!!

diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
 old mode 100644
 new mode 100755
 index bd6015e..56bcf60
 --- a/libutils/CallStack.cpp
 +++ b/libutils/CallStack.cpp
 @@ -26,6 +26,14 @@
  
  #include <backtrace/Backtrace.h>
  
 +extern "C" {
 +void call_stack_fun(const char* value){
 +    char buf[100];
 +    memset(buf, 0, sizeof(buf));
 +    snprintf(buf, sizeof(buf),"SGJ_%s",value);
 +    android::CallStack mCallStack(buf);
 +}
 +}
  namespace android {
  
  CallStack::CallStack() {

编译出libutils.so,重命名为libutilscallstack.so(当然也可以不重命名,主要是怕和原so冲突)

然后在想打印trace的C或者C++方法中通过 dlopendlsym方法去调用该方法,代码如下

--- a/services/camera/libcameraservice/CameraService.cpp
 +++ b/services/camera/libcameraservice/CameraService.cpp
 @@ -64,6 +64,8 @@
  #include "api2/CameraDeviceClient.h"
  #include "utils/CameraTraces.h"//++ begin
 #include <dlfcn.h>
 //++ end
  namespace {
      const char* kPermissionServiceName = "permission";
  }; // namespace anonymous
 @@ -181,6 +183,14 @@ void CameraService::onFirstRef()
  {
      ALOGI("CameraService process starting");
 //++ begin 
     void * prt_stack_lib = dlopen("/system/lib/libutilscallstack.so",RTLD_LAZY);
     ALOGE("SGJ dlopen %s:",dlerror());    //有问题时用这个dlerror看下错误信息
     void(*prt_stack_fun)(const char*) = (void (*)(const char *))dlsym(prt_stack_lib,"call_stack_fun");
     if (prt_stack_fun!=NULL) {
         prt_stack_fun("onFirstRef");
     }
     dlclose(prt_stack_lib);
 //++ end      BnCameraService::onFirstRef();


 




import android.util.Log;
Log.i(TAG, Log.getStackTraceString(new Throwable()));

c++,比如netd里

Android为方便Native层打印函数的调用堆栈,专门在system/core/libutils下设计了CallStack.cpp类
如果需要打印Native的stack只需要在自己的代码的mk文件中添加对libutils.so添加依赖,在类文件中include <utils/CallStack.h> 头文件。

实现方法如下:

.cpp文件
#include <utils/CallStack.h>

CallStack stack("powered by gaojian");
 

在编译文件添加对libutils.so的依赖,如下:

Android.mk
LOCAL_SHARED_LIBRARIES += libutils
 

该方案的缺点:

  1. 需要修改编译文件,有时候依赖libutils会不成功
  2. 只能在cpp文件中使用,无法在.c文件中使用

为解决该问题,本人百度、google研究了个遍,各种攻略都以失败告终,自己也相当郁闷,
难道就没有一个简单通用方法在c/c++文件中打印堆栈吗?
答案是肯定的

自己去研究了下CallStack .cpp,突发灵感,只要稍微对CallStack .cpp做修改,即可搞定这个问题!!!!

上代码:


diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
 old mode 100644
 new mode 100755
 index bd6015e..56bcf60
 --- a/libutils/CallStack.cpp
 +++ b/libutils/CallStack.cpp
 @@ -26,6 +26,14 @@
  
  #include <backtrace/Backtrace.h>
  
 +extern "C" {
 +void call_stack_fun(const char* value){
 +    char buf[100];
 +    memset(buf, 0, sizeof(buf));
 +    snprintf(buf, sizeof(buf),"SGJ_%s",value);
 +    android::CallStack mCallStack(buf);
 +}
 +}
  namespace android {
  
  CallStack::CallStack() {

编译出libutils.so,重命名为libutilscallstack.so(当然也可以不重命名,主要是怕和原so冲突)

然后在想打印trace的C或者C++方法中通过 dlopendlsym方法去调用该方法,代码如下

--- a/services/camera/libcameraservice/CameraService.cpp
 +++ b/services/camera/libcameraservice/CameraService.cpp
 @@ -64,6 +64,8 @@
  #include "api2/CameraDeviceClient.h"
  #include "utils/CameraTraces.h"//++ begin
 #include <dlfcn.h>
 //++ end
  namespace {
      const char* kPermissionServiceName = "permission";
  }; // namespace anonymous
 @@ -181,6 +183,14 @@ void CameraService::onFirstRef()
  {
      ALOGI("CameraService process starting");
 //++ begin 
     void * prt_stack_lib = dlopen("/system/lib/libutilscallstack.so",RTLD_LAZY);
     ALOGE("SGJ dlopen %s:",dlerror());    //有问题时用这个dlerror看下错误信息
     void(*prt_stack_fun)(const char*) = (void (*)(const char *))dlsym(prt_stack_lib,"call_stack_fun");
     if (prt_stack_fun!=NULL) {
         prt_stack_fun("onFirstRef");
     }
     dlclose(prt_stack_lib);
 //++ end

     BnCameraService::onFirstRef();