In android
NDK, I didn't find the traceback
function, so I need implement one myself.
The mytraceback
will be called in two call stack, one is f<10>()
and the other is in the global override new operator()
.
But seams only the first one works when I run the code in android. (On linux, seams both works).
So what's the difference to make the mytraceback
work in f<10>()
but not new operator()
?
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <unwind.h>
#ifdef LINUX
#include <execinfo.h>
#include <cxxabi.h>
#endif
#include <dlfcn.h>
#include <stdint.h>
#include <new>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
typedef struct {
size_t count;
void** addrs;
} stack_crawl_state_t;
static _Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
{
stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
if (state->count) {
void* ip = (void*)_Unwind_GetIP(context);
printf("Get the ip:%x\n", ip);
if (ip) {
state->addrs[0] = ip;
state->addrs++;
state->count--;
return _URC_NO_REASON;
}
}
return _URC_END_OF_STACK;
}
// implement android version backtrace function.
static int mybacktrace(void** addrs, size_t size)
{
printf("============begin unwind================\n");
stack_crawl_state_t state;
state.count = size;
state.addrs = addrs;
_Unwind_Backtrace(trace_function, (void*)&state);
return size - state.count;
}
void *operator new(size_t size) throw (std::bad_alloc)
{
void *callstack[16];
int i = mybacktrace(callstack, 16);
return malloc(size);
}
void operator delete(void *ptr) throw()
{
}
class X
{
};
template <int I> void f()
{
f<I-1>();
}
template <> void f<0>()
{
void *callstack[16];
int i = mybacktrace(callstack, 16);
}
int createObj2()
{
X * p = new X();
}
int createObj1()
{
createObj2();
}
int main()
{
createObj1();
f<10>();
}
result:
============begin unwind================
Get the ip:8898
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
Get the ip:88f0
============begin unwind================
Get the ip:8898
Get the ip:8960
Get the ip:8a6c
Get the ip:8a5c
Get the ip:8a4c
Get the ip:8a3c
Get the ip:8a2c
Get the ip:8a1c
Get the ip:8a0c
Get the ip:89fc
Get the ip:89ec
Get the ip:89dc
Get the ip:89c4
Get the ip:400823d8
Build command line:
export NDK_PATH=/home/zijingwu/Downloads/android-ndk-r9d
$NDK_PATH/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ -O0 -I$NDK_PATH/sources/cxx-stl/stlport/stlport -I. -DBSD=1 -DENABLE_ERROR_CATCH -DSOCKLEN_T=socklen_t -DHAVE_SOCKADDR_LEN=1 -DTIME_BASE=int --sysroot=$NDK_PATH/platforms/android-18/arch-arm/ -DANDROID -march=armv7-a -mfpu=neon -mfloat-abi=softfp -flax-vector-conversions -DPOSIX -Wno-unused-local-typedefs -g -gdwarf-2 -Wall -o test.o -c test.cpp
$NDK_PATH/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ -o -L. -nostdlib --sysroot=$NDK_PATH/platforms/android-18/arch-arm/ -Wl,--eh-frame-hdr,-m,armelf_linux_eabi,-z,noexecstack,-z,relro,-z,now -fPIC -Xlinker -start-group -Wl,--export-dynamic test.o $NDK_PATH/platforms/android-18/arch-arm/usr/lib/crtbegin_dynamic.o $NDK_PATH/platforms/android-18/arch-arm/usr/lib/crtend_android.o $NDK_PATH/platforms/android-18/arch-arm/usr/lib/liblog.so -L$NDK_PATH/sources/cxx-stl/stlport/libs/armeabi -Wl,-z,defs -Wl,--no-whole-archive -lstlport_shared -lstdc++ -lc -ldl -lm -lgcc -llog -Wl,--whole-archive -Xlinker --end-group -o test