gdb在源碼里面就有,路徑:prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-gdb
Gdb (可以使用完整Romcode 目錄中的gdb,也可以使用自己build的gdb)
下面提供的是在完整Rom code中的gdb路徑:
ARM64
prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-gdb
ARM
prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gdb
是arm64 還是arm 請查看tomstone文件:/data/tomstones/
ABI: 'arm64'
gdb調試android的bug需要兩樣東西:1.該版本對應的符號表 2.出現問題時的core dump文件(比如1421884199.1052.1000-system.core或者PROCESS_COREDUMP)
muhe221@muhe:~/share/soft/gdb$ aarch64-linux-android-gdb
..........
(gdb) file ./symbols/system/bin/app_process64
Reading symbols from app_process64...done.
(gdb) set solib-search-path ../symbols/system/lib64/
(gdb) set solib-absolute-prefix ../symbols/
(gdb) core PROCESS_COREDUMP
warning: exec file is newer than core file.
[New LWP 2289]
[New LWP 927]
[New LWP 1358]
[New LWP 1357]
[New LWP 1651]
[New LWP 22572]
.......
warning: Could not load shared library symbols for 34 libraries, e.g. libaed.so.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Program terminated with signal SIGSEGV, Segmentation fault.
#0 UnCompress (this=0x654ce910) at art/runtime/mirror/object_reference.h:66
66 art/runtime/mirror/object_reference.h: No such file or directory.
(gdb)
----------------------------------------------------
或者以下方式:
$ aarch64-linux-android-gdb ./symbols/system/bin/app_process64 -c 1421884199.1052.1000-system.core
(gdb) set solib-search-path symbols/system/lib64
(gdb) set solib-absolute-prefix symbols/
---------------------------------------------------------
(gdb) bt
#0 UnCompress (this=0x654ce910) at art/runtime/mirror/object_reference.h:66
#1 AsMirrorPtr (this=0x654ce910) at art/runtime/mirror/object_reference.h:37
#2 Barrier<art::mirror::Class, (art::ReadBarrierOption)0> (ref_addr=0x654ce910, offset=..., obj=0x654ce910) at art/runtime/read_barrier-inl.h:42
#3 GetFieldObject<art::mirror::Class, (art::VerifyObjectFlags)0, (art::ReadBarrierOption)0, false> (field_offset=..., this=0x654ce910) at art/runtime/mirror/object-inl.h:603
#4 GetClass<(art::VerifyObjectFlags)0, (art::ReadBarrierOption)0> (this=0x654ce910) at art/runtime/mirror/object-inl.h:46
#5 art::FaultManager::IsInGeneratedCode (this=0x7f888a1e08 <art::fault_manager>, siginfo=0x7f6a762da0, context=0x7f6a762e20, check_dex_pc=true) at art/runtime/fault_handler.cc:246
#6 0x0000007f8874c128 in art::FaultManager::HandleFault (this=0x7f888a1e08 <art::fault_manager>, sig=11, info=0x7f6a762da0, context=0x7f6a762e20) at art/runtime/fault_handler.cc:144
#7 <signal handler called>
#8 UnCompress (this=0x48506749) at art/runtime/mirror/object_reference.h:66
#9 AsMirrorPtr (this=0x48506749) at art/runtime/mirror/object_reference.h:37
#10 Barrier<art::mirror::PrimitiveArray<unsigned short>, (art::ReadBarrierOption)0> (ref_addr=0x48506749, offset=..., obj=0x48506741) at art/runtime/read_barrier-inl.h:42
#11 GetFieldObject<art::mirror::PrimitiveArray<unsigned short>, (art::VerifyObjectFlags)0, (art::ReadBarrierOption)0, false> (field_offset=..., this=0x48506741) at art/runtime/mirror/object-inl.h:603
#12 GetCharArray (this=0x48506741) at art/runtime/mirror/string-inl.h:37
#13 art::JNI::GetStringCritical (env=<optimized out>, java_string=0x7f654cf00c, is_copy=0x0) at art/runtime/jni_internal.cc:2018
#14 0x0000007f8266fddc in GetStringCritical (isCopy=0x0, string=0x7f654cf00c, this=0x55a3dd5c70) at libnativehelper/include/nativehelper/jni.h:1005
#15 android::convertJString (env=env@entry=0x55a3dd5c70, str=str@entry=0x7f654cf00c) at frameworks/base/services/core/jni/com_android_server_am_MemoryLogUtilAM.cpp:26
#16 0x0000007f8266ffa4 in android::android_server_am_MemoryLogUtilAm_dumpProcessStats (env=0x55a3dd5c70, clazz=<optimized out>, pid=762, name=0x0, reason=0x7f654cf008, service=0x7f654cf00c,
provider=0x7f654cf010, ishomekilled=<optimized out>) at frameworks/base/services/core/jni/com_android_server_am_MemoryLogUtilAM.cpp:173
#17 0x0000007f720655b4 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
disas反匯編后 “=>”表示出錯的匯編代碼位置
(gdb) disas Dump of assembler code for function memmove: ............ 0x0000007fb3a15f00 <+0>: cmp x0, x1 0x0000007fb3a15f04 <+4>: b.cc 0x7fb3a16094 <memmove+404> 0x0000007fb3a160d8 <+472>: ldp x7, x8, [x1,#-16] => 0x0000007fb3a160dc <+476>: stp x7, x8, [x6,#-16] 0x0000007fb3a160e0 <+480>: tbz w2, #3, 0x7fb3a160ec <memmove+492> 0x0000007fb3a160e4 <+484>: ldr x3, [x1],#8 ............
info r查看寄存器的情況
(gdb) info r x0 0x7f9332bfd8 547930423256 x1 0x7f9332bff3 547930423283 x2 0x1a 26 x3 0x10 16 x4 0x40100401 1074791425 x5 0xaaa8a800aaaa 187641349843626 x6 0x7f9332bfe8 547930423272 x7 0x7320524556495244 8295720971370320452 x8 0x20706968635f7465 2337484103670002789 x9 0x7f7f7f7f7f7f7f7f 9187201950435737471 x10 0x101010101010101 72340172838076673 x11 0x101010101010101 72340172838076673 x12 0x38 56 x13 0xffffffffffffffff -1 x14 0xff00000000000000 -72057594037927936 x15 0x25 37 x16 0x7fb2fabda8 548463623592 x17 0x7fb3a15f00 548474543872 x18 0x7fb3aad7c8 548475164616 x19 0x7fb2fad000 548463628288 x20 0x7f9332bfd8 547930423256 x21 0x24 36 x22 0x7fb2fae000 548463632384 x23 0x7f97bfd688 548006778504 x24 0x7f97bfd648 548006778440 x25 0x7f97bff95c 548006787420 x26 0x7f97bfff60 548006788960 x27 0x7fb03d5000 548417654784 x28 0x7f97bff6c0 548006786752 x29 0x7f97bfd5c0 548006778304 x30 0x7fb2f97c60 548463541344 sp 0x7f97bfd5c0 0x7f97bfd5c0 pc 0x7fb3a160dc 0x7fb3a160dc <memmove+476> cpsr 0x80000000 2147483648 fpsr 0x10 16 fpcr 0x0 0
(gdb) f 6 // frame 簡寫f
#6 0x0000007f8874c128 in art::FaultManager::HandleFault (this=0x7f888a1e08 <art::fault_manager>, sig=11, info=0x7f6a762da0, context=0x7f6a762e20) at art/runtime/fault_handler.cc:144
144 art/runtime/fault_handler.cc: No such file or directory.
(gdb) p info
$9 = (siginfo_t *) 0x7f6a762da0
(gdb) p *info
$10 = {si_signo = 11, si_errno = 0, si_code = 2, _sifields = {_pad = {1213228873, 0 <repeats 27 times>}, _kill = {_pid = 1213228873, _uid = 0}, _timer = {_tid = 1213228873, _overrun = 0,
_pad = 0x7f6a762db8 "", _sigval = {sival_int = 0, sival_ptr = 0x0}, _sys_private = 0}, _rt = {_pid = 1213228873, _uid = 0, _sigval = {sival_int = 0, sival_ptr = 0x0}}, _sigchld = {
_pid = 1213228873, _uid = 0, _status = 0, _utime = 0, _stime = 0}, _sigfault = {_addr = 0x48506749, _addr_lsb = 0}, _sigpoll = {_band = 1213228873, _fd = 0}, _sigsys = {_call_addr = 0x48506749,
_syscall = 0, _arch = 0}}}
(gdb)
(gdb) p/d 0x48506749
$12 = 1213228873
(gdb) p/x 0x123 + 0x321
$13 = 0x444
//根據siginfo_t的結構,判斷出錯地址是0x48506749
//根據#10 發現0x48506749 = 0x48506741 + 0x8
#10 Barrier<art::mirror::PrimitiveArray<unsigned short>, (art::ReadBarrierOption)0> (ref_addr=0x48506749, offset=..., obj=0x48506741) at art/runtime/read_barrier-inl.h:42
//那么我們應該繼續查找0x48506741,這個值應該是出錯了
#12 GetCharArray (this=0x48506741) at art/runtime/mirror/string-inl.h:37
art/runtime/mirror/string-inl.h
inline CharArray* String::GetCharArray() {
return GetFieldObject<CharArray>(ValueOffset());
}
art/runtime/jni_internal.cc
static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
CHECK_NON_NULL_ARGUMENT(java_string);
ScopedObjectAccess soa(env);
mirror::String* s = soa.Decode<mirror::String*>(java_string);
mirror::CharArray* chars = s->GetCharArray(); ////////
int32_t offset = s->GetOffset();
gc::Heap* heap = Runtime::Current()->GetHeap();
if (heap->IsMovableObject(chars)) {
StackHandleScope<1> hs(soa.Self());
HandleWrapper<mirror::CharArray> h(hs.NewHandleWrapper(&chars));
heap->IncrementDisableMovingGC(soa.Self());
}
if (is_copy != nullptr) {
*is_copy = JNI_FALSE;
}
return static_cast<jchar*>(chars->GetData() + offset);
}
(gdb) p s
$75 = <optimized out> //這是是指對應的代碼被優化過了,所以找不到對應的值
(gdb) p *s
value has been optimized out
(gdb) p java_string
$76 = (jstring) 0x7f654cf00c
(gdb) x java_string // 這個必須分析出java_string是指向指針的指針,有點運氣的成分。
0x7f654cf00c: 0x48506741 //也就是說java_string是有問題的,它間接指向的內存空間值有問題
(gdb)
(gdb) f 16
#16 0x0000007f8266ffa4 in android::android_server_am_MemoryLogUtilAm_dumpProcessStats (env=0x55a3dd5c70, clazz=<optimized out>, pid=762, name=0x0, reason=0x7f654cf008, service=0x7f654cf00c,
provider=0x7f654cf010, ishomekilled=<optimized out>) at frameworks/base/services/core/jni/com_android_server_am_MemoryLogUtilAM.cpp:173
173 in frameworks/base/services/core/jni/com_android_server_am_MemoryLogUtilAM.cpp
(gdb) p service
$78 = (jstring) 0x7f654cf00c
frameworks/base/services/core/jni/com_android_server_am_MemoryLogUtilAM.cpp
static jstring android_server_am_MemoryLogUtilAm_dumpProcessStats(JNIEnv* env,
jobject clazz, jint pid, jstring name, jstring reason,
jstring service, jstring provider, jboolean ishomekilled) {
String8 home_restart;
char filename[64];
char line[256];
char *process_name = NULL;
int platform = MemoryMeasureHelper::getPlatformType();
snprintf(filename, sizeof(filename), "/proc/%d/oom_adj", pid);
FILE *file = fopen(filename, "r");
if (!file)
return NULL;
int oom_adj = -100;
if (fgets(line, sizeof(line), file))
sscanf(line, "%d", &oom_adj);
fclose(file);
String8 name8;
if (name != NULL) {
name8 = convertJString(env, name);
process_name = (char*) name8.string();
} else {
snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
file = fopen(filename, "r");
if (!file)
return env->NewStringUTF(home_restart.string());
fscanf(file, "%s", line); // fscanf(file, "%255s", line);
if (strlen(line) != 0) {
process_name = (char*) malloc(strlen(line) + 1);
memset(process_name, 0, strlen(line) + 1);
strcpy(process_name, line);
} else {
process_name = (char*) malloc(7 + 1); //unknown string length = 7
memset(process_name, 0, 7 + 1);
strcpy(process_name, "unknown");
}
fclose(file);
}
String8 extraInfo;
String8 service8 = convertJString(env, service);
String8 provider8 = convertJString(env, provider);
...........
}
//到這里就發現service的值不正確,到底是被改了,還是傳進來的service不對?
函數棧已經到底了。再深入就是java代碼。一般來說java傳值到本地不會出錯。
這里是service傳入的時候是正確的。但是之后被人修改了。
(gdb) p &line[0xff]
$188 = 0x7f654cebe7 "TI3LjAuMC4xIiBkb3Bpbmc9InRydWUiCiAgICBpcGM9Imh0dHAiIGlwY2Nvbm5lY3QyPSIxMjcuMC4wLjE6MzM4OTYvQUN3QUFRPT0iCiAgICBsb2NhbGlwcD0iMTAuMTE2LjIwOC4xMzM6NTI2OTkiIG1vZHVsZWRpcj0icG12MzI4LTE1MDUwODAtMCIKICAgIHBpZ"...
0x7f654cebe7是字符串首地址。
前面看到我們出錯的jstring內存地址是:0x7f654cf00c;而0x7f654cf00c - 0x7f654cebe7= 0x524,那么接下來我們就根據line查看這個地址:
(gdb) p &line[0x524]
$189 = 0x7f654cf00c "AgPHNlcnZlciBlbmFibGVkPSJ0cnVlIiB1c2VvbGQ9InRydWUiLz4KICAgICAgPGNvbnNvbGUgZW5hYmxlZD0iZmFsc2UiIG5vc3Rkb3V0PSJmYWxzZSIvPgogICAgICA8ZmlsZSBlbmFibGVkPSJmYWxzZSIgbG9ncGF0aD0iLiIvPgogICAgPC9sb2c+CiAgPC9wbW"...
(gdb) x &line[0x524]
0x7f654cf00c: 0x48506741
typedef struct siginfo { int si_signo; int si_code; int si_errno; int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3]; union { int _pad[SI_PAD_SIZE]; struct { pid_t _pid; _ _ARCH_SI_UID_T _uid; } _kill; struct { timer_t _tid; int _overrun; char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; sigval_t _sigval; int _sys_private; } _timer; struct { pid_t _pid; __ARCH_SI_UID_T _uid; sigval_t _sigval; } _rt; struct { pid_t _pid; __ARCH_SI_UID_T _uid; int _status; clock_t _utime; clock_t _stime; } _sigchld; struct { pid_t _pid; clock_t _utime; int _status; clock_t _stime; } _irix_sigchld; struct { void __user *_addr; #ifdef __ARCH_SI_TRAPNO int _trapno; #endif } _sigfault; struct { __ARCH_SI_BAND_T _band; int _fd; } _sigpoll; } _sifields; } siginfo_t;
(gdb) bt #0 0x0000000000000000 in ?? () #1 0x0000007f78ca5200 in sputn (__n=1, __s=0x7f7876ded5 "\"", this=0x7f7876e298) at external/libcxx/include/streambuf:360 #2 __pad_and_output<char, std::__1::char_traits<char> > (__fl=32 ' ', __iob=..., __oe=0x7f7876ded6 "", __op=0x7f7876ded5 "\"", __ob=0x7f7876dea5 "", __s=...) at external/libcxx/include/locale:1515 #3 std::__1::__put_character_sequence<char, std::__1::char_traits<char> > (__os=..., __str=__str@entry=0x7f7876df65 "ult", __len=__len@entry=1) at external/libcxx/include/ostream:755 #4 0x0000007f78fd55c4 in operator<< <std::__1::char_traits<char> > (__c=117 'u', __os=...) at external/libcxx/include/ostream:820 #5 art::Thread::DumpState (os=..., thread=thread@entry=0x0, tid=tid@entry=1186) at art/runtime/thread.cc:962 #6 0x0000007f78fde3d4 in DumpUnattachedThread (tid=1186, os=...) at art/runtime/thread_list.cc:123 #7 art::ThreadList::DumpUnattachedThreads (this=this@entry=0x55aa302160, os=...) at art/runtime/thread_list.cc:151 #8 0x0000007f78fe5054 in art::ThreadList::DumpForSigQuit (this=0x55aa302160, os=...) at art/runtime/thread_list.cc:117 #9 0x0000007f78fad0b4 in art::Runtime::DumpForSigQuit (this=0x55aa2fb3a0, os=...) at art/runtime/runtime.cc:1258 #10 0x0000007f78fbb0c8 in art::SignalCatcher::HandleSigQuit (this=this@entry=0x55aa78e400) at art/runtime/signal_catcher.cc:144 #11 0x0000007f78fbbcd8 in art::SignalCatcher::Run (arg=0x55aa78e400) at art/runtime/signal_catcher.cc:211 #12 0x0000007f7c854048 in __pthread_start (arg=0x7f7876e450, arg@entry=<error reading variable: value has been optimized out>) at bionic/libc/bionic/pthread_create.cpp:199 #13 0x0000007f7c806848 in __start_thread (fn=<optimized out>, arg=<optimized out>) at bionic/libc/bionic/clone.cpp:41 #14 0x0000000000000000 in ?? () (gdb) (gdb) p __s //可以直接打印部分變量 $23 = (const std::__1::basic_streambuf<char, std::__1::char_traits<char> >::char_type *) 0x7f7876ded5 "\"" (gdb) p (char*)0x7f7876ded5 //如果是地址 則一定要強轉,否則不能識別類型 $27 = 0x7f7876ded5 "\"" (gdb)
CPU必須具有某些手段來確定下一條取指指令的地址。程序計數器(PC )正是起到這種作用,所以通常又稱之為‘指令計數器’。CPU總是按照PC的指向對指令序列進行取指、譯碼和執行,也就是說,最終是PC 決定了程序運行流向。故而,程序計數器(PC )屬於特別功能寄存器范疇,不能自由地用於存儲其他運算數據。
在程序開始執行前,將程序指令序列的起始地址,即程序的第一條指令所在的內存單元地址送入PC,CPU 按照 PC的指示從內存讀取第一條指令(取指)。當執行指令時,CPU自動地修改PC 的內容,即每執行一條指令PC增加一個量,這個量等於指令所含的字節數(指令字節數),使 PC總是指向下一條將要取指的指令地址。由於大多數指令都是按順序來執行的,所以修改PC 的過程通常只是簡單的對PC 加“指令字節數”。
當程序轉移時,轉移指令執行的最終結果就是要改變PC的值,此PC值就是轉去的目 標地址。處理器總是按照PC 指向取指、譯碼、執行,以此實現了程序轉移。
AED : check process 3381 name:biledata:remote AED : tid 3386 abort msg address is:0x0000000000000000 si_code is:1 (request from 3381:10036) AED : BOOM: pid=3381 uid=10036 gid=10036 tid=3386 AED : [OnPurpose Redunant in void preset_info(aed_report_record*, int, int)] pid: 3381, tid: 3386, name: Signal Catcher >>> com.htc.mobiledata:remote <<< DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** DEBUG: Build fingerprint: 'htc/himar2uhl_00999/htc_himar2uhl:6.0/MRA58K/737597.1:user/release-keys' DEBUG: Revision: '0' DEBUG: ABI: 'arm64' DEBUG: pid: 3381, tid: 3386, name: Signal Catcher >>> com.htc.mobiledata:remote <<< DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x20 //這個是地址,而不是寄存器x20 DEBUG: x0 0000000000000014 x1 0000000000000000 x2 0000000000000000 x3 0000000000000000 DEBUG: x4 0000007f7a47fbe8 x5 00000000000000b8 x6 0000000070397d3c x7 0000000000080011 DEBUG: x8 00000055b7e20420 x9 0000000000000004 x10 0000000070397d10 x11 0000000070098d98 DEBUG: x12 0000000070098db8 x13 0000007f7aeb7dd0 x14 0000007f7ace4818 x15 0000007f7aeb7dd0 DEBUG: x16 0000007f7aebf968 x17 0000007f7e502240 x18 00000055b7e290c0 x19 0000007f7a47fbe8 DEBUG: x20 00000000706cef90 x21 0000007f7aec0000 x22 0000007f7aec0000 x23 00000055b6139c20 DEBUG: x24 0000007f7aec0000 x25 0000007f7aeb7d70 x26 0000007f7ae116a0 x27 0000007f7aec0000 DEBUG: x28 0000000000000000 x29 0000007f7a47f8d0 x30 0000007f7ace4888 DEBUG: sp 0000007f7a47f8d0 pc 0000007f7a9ba3f0 pstate 0000000000000000 DEBUG: DEBUG: backtrace: DEBUG: #00 pc 00000000001303f0 /system/lib64/libart.so (art::ArtMethod::ToDexPc(unsigned long, bool)+20) DEBUG: #01 pc 000000000045a884 /system/lib64/libart.so (art::StackDumpVisitor::VisitFrame()+108) DEBUG: #02 pc 0000000000444640 /system/lib64/libart.so (art::StackVisitor::WalkStack(bool)+172) DEBUG: #03 pc 0000000000457808 /system/lib64/libart.so (art::Thread::DumpJavaStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+296) DEBUG: #04 pc 000000000045de28 /system/lib64/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, BacktraceMap*, bool) const+516) DEBUG: #05 pc 000000000046c610 /system/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+2084) DEBUG: #06 pc 000000000046d044 /system/lib64/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+492) DEBUG: #07 pc 00000000004350b0 /system/lib64/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+96) DEBUG: #08 pc 00000000004430c4 /system/lib64/libart.so (art::SignalCatcher::HandleSigQuit()+1256) DEBUG: #09 pc 0000000000443cd4 /system/lib64/libart.so (art::SignalCatcher::Run(void*)+452) DEBUG: #10 pc 000000000006a044 /system/lib64/libc.so (__pthread_start(void*)+52) DEBUG: #11 pc 000000000001c844 /system/lib64/libc.so (__start_thread+16) AED : request.action: 0 AED : dashboard_record_update() : rec->module = com.htc.mobiledata:remote AED : Update record[0]
查看某個地址附近的內存
(gdb) x/64ch 0x7f7a47fbe8 0x7f7a47fbe8: -48 '\320' -21 '\353' 127 '\177' 0 '\000' -64 '\300' 55 '7' 85 'U' 0 '\000' 0x7f7a47fbf8: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0x7f7a47fc08: 80 'P' -38 '\332' 127 '\177' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0x7f7a47fc18: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0x7f7a47fc28: 16 '\020' -30 '\342' 85 'U' 0 '\000' 16 '\020' 71 'G' 127 '\177' 0 '\000' 0x7f7a47fc38: -64 '\300' 55 '7' 85 'U' 0 '\000' 1 '\001' 0 '\000' 0 '\000' 0 '\000' 0x7f7a47fc48: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0x7f7a47fc58: 0 '\000' 0 '\000' -15 '\361' -85 '\253' 16 '\020' 71 'G' 127 '\177' 0 '\000'
memory near x25: 0000000013c282e0 0061002e0065006c 006f00720064006e l.e...a.n.d.r.o. 0000000013c282f0 0061002e00640069 002e007300700070 i.d...a.p.p.s... 0000000013c28300 0069006e00650067 00650067002e0065 g.e.n.i.e...g.e. 0000000013c28310 007700650069006e 0065006700640069 n.i.e.w.i.d.g.e. 0000000013c28320 00720065006b0074 0061006e00650020 t.k.e.r. .e.n.a. 0000000013c28330 003d0065006c0062 0000000000000000 b.l.e.=......... 0000000013c28340 000000006ff93328 000000001331cd60 (3.o....`.1..... 0000000013c28350 0000000000000000 145fdb4000000000 ............@._. 0000000013c28360 0000000000000000 0000000000000000 ................ 0000000013c28370 00000010fffffffe 0000000000000000 ................ 0000000013c28380 000000006fe8fac0 070b61d300000016 ...o.........a.. 0000000013c28390 006c006f00640020 0073005f00790062 .d.o.l.b.y._.s. 0000000013c283a0 006b006100650070 0065005f00720065 p.e.a.k.e.r._.e. 0000000013c283b0 006c00620061006e 00000000003d0065 n.a.b.l.e.=..... 0000000013c283c0 000000006fe8fac0 4e2c59b000000016 ...o.........Y,N 0000000013c283d0 006f0044006d0020 005300790062006c .m.D.o.l.b.y.S. (gdb) x/64ch 0x13c282c0 0x13c282c0: -64 '\300' -24 '\350' 0 '\000' 0 '\000' 24 '\030' 0 '\000' 0 '\000' 0 '\000' 0x13c282d0: 99 'c' 111 'o' 109 'm' 46 '.' 103 'g' 111 'o' 111 'o' 103 'g' 0x13c282e0: 108 'l' 101 'e' 46 '.' 97 'a' 110 'n' 100 'd' 114 'r' 111 'o' 0x13c282f0: 105 'i' 100 'd' 46 '.' 97 'a' 112 'p' 112 'p' 115 's' 46 '.' 0x13c28300: 103 'g' 101 'e' 110 'n' 105 'i' 101 'e' 46 '.' 103 'g' 101 'e' 0x13c28310: 110 'n' 105 'i' 101 'e' 119 'w' 105 'i' 100 'd' 103 'g' 101 'e' 0x13c28320: 116 't' 107 'k' 101 'e' 114 'r' 32 ' ' 101 'e' 110 'n' 97 'a' 0x13c28330: 98 'b' 108 'l' 101 'e' 61 '=' 0 '\000' 0 '\000' 0 '\000' 0 '\000'
android.apps.genie.geniewidgetker
java層是一個字符占1個字節
c++層是unicode 所以一個字符占2個字節?
g:0x67 e:0x65 n:0x6e i:0x69
0000000013c28300 0069006e00650067 00650067002e0065 g.e.n.i.e...g.e.
0 i 0 n 0 e 0 g 0 e 0 g 0 . 0 e
按8字節去取小端序列,轉換成大端, 分別為:
g0e0n0i0
e0.0g0e0
連在一起則為g0e0n0i0e0.0g0e0
即g.e.n.i.e...g..0
(gdb) help x Examine memory: x/FMT ADDRESS. ADDRESS is an expression for the memory address to examine. FMT is a repeat count followed by a format letter and a size letter. Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char), s(string) and z(hex, zero padded on the left). Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes). The specified number of objects of the specified size are printed according to the format.
x/16c address //表示查看address地址后面的16個char類型的值
x/16ch address
x/16z address
其它類推
(gdb) f 1 #1 0x0000007f7acce284 in art::StackVisitor::GetDexPc (this=this@entry=0x7f7a47fbe8, abort_on_failure=abort_on_failure@entry=false) (gdb) p (this ) $16 = (const art::StackVisitor * const) 0x7f7a47fbe8 (gdb) p (Thread*) (this + 1 ) $20 = (art::Thread *) 0x7f7a47fc30 這里這樣計算是錯誤的 因為this是StackVisitor, this + 1 這樣實際得到的是[this + sizeof(StackVisitor)]
class StackVisitor{ private: Thread* const thread_; const StackWalkKind walk_kind_; ShadowFrame* cur_shadow_frame_; //offset #24 ArtMethod** cur_quick_frame_; //offset #32 uintptr_t cur_quick_frame_pc_; //offset #40 size_t num_frames_; size_t cur_depth_; Context* const context_; };
一般來說cur_shadow_frame_ 的偏移是offset #16, 事實上並非如此,它的值是offset#24
因為代碼運行的時候它的前面有個虛函數表指針
(gdb) p *this $38 = {_vptr.StackVisitor = 0x7f7aeb7dd0 <vtable for art::StackDumpVisitor+16>, thread_ = 0x55b637f6c0,
walk_kind_ = art::StackVisitor::kIncludeInlinedFrames, cur_shadow_frame_ = 0x0, cur_quick_frame_ = 0x7f74da5250, cur_quick_frame_pc_ = 0,
num_frames_ = 0, cur_depth_ = 0, context_ = 0x55b7e20210}
(gdb) bt #0 0x0000007f7a9ba3f0 in art::ArtMethod::ToDexPc (this=0x14, pc=0, abort_on_failure=false) at art/runtime/art_method.cc:180 #1 0x0000007f7acce284 in art::StackVisitor::GetDexPc (this=this@entry=0x7f7a47fbe8, abort_on_failure=abort_on_failure@entry=false) at art/runtime/stack.cc:114 #2 0x0000007f7ace4888 in art::StackDumpVisitor::VisitFrame (this=0x7f7a47fbe8) at art/runtime/thread.cc:1069 #3 0x0000007f7acce644 in art::StackVisitor::WalkStack (this=this@entry=0x7f7a47fbe8, include_transitions=include_transitions@entry=false) at art/runtime/stack.cc:737 #4 0x0000007f7ace180c in art::Thread::DumpJavaStack (this=this@entry=0x55b637f6c0, os=...) at art/runtime/thread.cc:1199 #5 0x0000007f7ace7e2c in DumpStack (dump_all_threads=true, backtrace_map=0x0, os=..., this=0x55b637f6c0) at art/runtime/thread.cc:1234 #6 art::Thread::Dump (this=0x55b637f6c0, os=..., backtrace_map=backtrace_map@entry=0x0, dump_all_threads=dump_all_threads@entry=true) at art/runtime/thread.cc:724 #7 0x0000007f7acf6614 in art::ThreadList::Dump (this=this@entry=0x55b611a6a0, os=...) at art/runtime/thread_list.cc:253 #8 0x0000007f7acf7048 in art::ThreadList::DumpForSigQuit (this=0x55b611a6a0, os=...) at art/runtime/thread_list.cc:116 #9 0x0000007f7acbf0b4 in art::Runtime::DumpForSigQuit (this=0x55b61143a0, os=...) at art/runtime/runtime.cc:1258 #10 0x0000007f7accd0c8 in art::SignalCatcher::HandleSigQuit (this=this@entry=0x55b6364740) at art/runtime/signal_catcher.cc:144 #11 0x0000007f7accdcd8 in art::SignalCatcher::Run (arg=0x55b6364740) at art/runtime/signal_catcher.cc:211 #12 0x0000007f7e552048 in __pthread_start (arg=0x7f7a480450, arg@entry=<error reading variable: value has been optimized out>) at bionic/libc/bionic/pthread_create.cpp:199 #13 0x0000007f7e504848 in __start_thread (fn=<optimized out>, arg=<optimized out>) at bionic/libc/bionic/clone.cpp:41 #14 0x0000000000000000 in ?? () (gdb) (gdb) f 1 #1 0x0000007f7acce284 in art::StackVisitor::GetDexPc (this=this@entry=0x7f7a47fbe8, abort_on_failure=abort_on_failure@entry=false) at art/runtime/stack.cc:114 114 art/runtime/stack.cc: No such file or directory. (gdb) p this $37 = (const art::StackVisitor * const) 0x7f7a47fbe8 (gdb) p *this $38 = {_vptr.StackVisitor = 0x7f7aeb7dd0 <vtable for art::StackDumpVisitor+16>, thread_ = 0x55b637f6c0, walk_kind_ = art::StackVisitor::kIncludeInlinedFrames, cur_shadow_frame_ = 0x0, cur_quick_frame_ = 0x7f74da5250, cur_quick_frame_pc_ = 0, num_frames_ = 0, cur_depth_ = 0, context_ = 0x55b7e20210} (gdb) x/16x this // 或者x/16z 有時候數據對齊切換不過來,不知道為什么 0x7f7a47fbe8: 0x0000007f7aeb7dd0 0x00000055b637f6c0 0x7f7a47fbf8: 0x0000000000000000 0x0000000000000000 0x7f7a47fc08: 0x0000007f74da5250 0x0000000000000000 0x7f7a47fc18: 0x0000000000000000 0x0000000000000000 0x7f7a47fc28: 0x00000055b7e20210 0x0000007f7a47ff10 0x7f7a47fc38: 0x00000055b637f6c0 0x0000000000000001 0x7f7a47fc48: 0x0000000000000000 0x0000000000000000 0x7f7a47fc58: 0x76ab3ff100000000 0x0000007f7a47fd10 (gdb) p (Thread*)*(0x7f7a47fbe8 + 0x8) //錯誤的做法 $39 = (art::Thread *) 0xffffffffb637f6c0 (gdb) p (*this).thread_ $40 = (art::Thread * const) 0x55b637f6c0 (gdb) p &((*this).thread_) $41 = (art::Thread * const *) 0x7f7a47fbf0 (gdb) p (Thread* const*)(0x7f7a47fbe8 + 0x8) $45 = (art::Thread * const *) 0x7f7a47fbf0 (gdb) p *(Thread* const*)(0x7f7a47fbe8 + 0x8) $46 = (art::Thread * const) 0x55b637f6c0
(gdb) x/16ch this //這個貌似顯示有問題,沒看懂 0x7f7a47fbe8: -48 '\320' -21 '\353' 127 '\177' 0 '\000' -64 '\300' 55 '7' 85 'U' 0 '\000' 0x7f7a47fbf8: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' (gdb) x/16c this 0x7f7a47fbe8: -48 '\320' 125 '}' -21 '\353' 122 'z' 127 '\177' 0 '\000' 0 '\000' 0 '\000' 0x7f7a47fbf0: -64 '\300' -10 '\366' 55 '7' -74 '\266' 85 'U' 0 '\000' 0 '\000' 0 '\000' (gdb) x/16z this 0x7f7a47fbe8: 0xd0 0x7d 0xeb 0x7a 0x7f 0x00 0x00 0x00 0x7f7a47fbf0: 0xc0 0xf6 0x37 0xb6 0x55 0x00 0x00 0x00 (gdb) x/16a this 0x7f7a47fbe8: 0x7f7aeb7dd0 <_ZTVN3art16StackDumpVisitorE+16> 0x55b637f6c0 0x7f7a47fbf8: 0x0 0x0 0x7f7a47fc08: 0x7f74da5250 0x0 0x7f7a47fc18: 0x0 0x0 0x7f7a47fc28: 0x55b7e20210 0x7f7a47ff10 0x7f7a47fc38: 0x55b637f6c0 0x1 0x7f7a47fc48: 0x0 0x0 0x7f7a47fc58: 0x76ab3ff100000000 0x7f7a47fd10 (gdb) x/16z this 0x7f7a47fbe8: 0x0000007f7aeb7dd0 0x00000055b637f6c0 0x7f7a47fbf8: 0x0000000000000000 0x0000000000000000 0x7f7a47fc08: 0x0000007f74da5250 0x0000000000000000 0x7f7a47fc18: 0x0000000000000000 0x0000000000000000 0x7f7a47fc28: 0x00000055b7e20210 0x0000007f7a47ff10 0x7f7a47fc38: 0x00000055b637f6c0 0x0000000000000001 0x7f7a47fc48: 0x0000000000000000 0x0000000000000000 0x7f7a47fc58: 0x76ab3ff100000000 0x0000007f7a47fd10 (gdb) p 0x7f $53 = 127 (gdb) p 0x7a $54 = 122 (gdb) p 0x7d $55 = 125 (gdb) p 0xd0 $56 = 208
、
(gdb) info thread // 查看所有線程 Id Target Id Frame * 14 LWP 3609 memcpy () at bionic/libc/arch-arm64/generic/bionic/memcpy_base.S:58 13 LWP 3610 __epoll_pwait () at bionic/libc/arch-arm64/syscalls/__epoll_pwait.S:9 12 LWP 3611 __epoll_pwait () at bionic/libc/arch-arm64/syscalls/__epoll_pwait.S:9 11 LWP 3381 syscall () at bionic/libc/arch-arm64/bionic/syscall.S:41 10 LWP 3492 __ioctl () at bionic/libc/arch-arm64/syscalls/__ioctl.S:7 9 LWP 3391 syscall () at bionic/libc/arch-arm64/bionic/syscall.S:41 8 LWP 3390 syscall () at bionic/libc/arch-arm64/bionic/syscall.S:41 7 LWP 3389 syscall () at bionic/libc/arch-arm64/bionic/syscall.S:41 6 LWP 3388 syscall () at bionic/libc/arch-arm64/bionic/syscall.S:41 5 LWP 3387 recvmsg () at bionic/libc/arch-arm64/syscalls/recvmsg.S:7 4 LWP 3613 __epoll_pwait () at bionic/libc/arch-arm64/syscalls/__epoll_pwait.S:9 3 LWP 3393 __ioctl () at bionic/libc/arch-arm64/syscalls/__ioctl.S:7 2 LWP 3392 __ioctl () at bionic/libc/arch-arm64/syscalls/__ioctl.S:7 1 LWP 3386 0x0000007f7a9ba3f0 in art::ArtMethod::ToDexPc (this=0x14, pc=0, abort_on_failure=false) at art/runtime/art_method.cc:180 (gdb) thread 2 //線程切換 [Switching to thread 2 (LWP 3392)] #0 __ioctl () at bionic/libc/arch-arm64/syscalls/__ioctl.S:7 7 bionic/libc/arch-arm64/syscalls/__ioctl.S: No such file or directory. (gdb) bt #0 __ioctl () at bionic/libc/arch-arm64/syscalls/__ioctl.S:7 #1 0x0000007f7e55e5f0 in ioctl (fd=<optimized out>, request=<optimized out>) at bionic/libc/bionic/ioctl.c:41 #2 0x0000007f7e8a1880 in android::IPCThreadState::talkWithDriver (this=this@entry=0x55b6367ae0, doReceive=doReceive@entry=true) at vendor/htc/native/libs/binder/IPCThreadState.cpp:902 #3 0x0000007f7e8a218c in android::IPCThreadState::getAndExecuteCommand (this=this@entry=0x55b6367ae0) at vendor/htc/native/libs/binder/IPCThreadState.cpp:427 #4 0x0000007f7e8a22b8 in android::IPCThreadState::joinThreadPool (this=0x55b6367ae0, isMain=true) at vendor/htc/native/libs/binder/IPCThreadState.cpp:505 #5 0x0000007f7e8ab5e0 in android::PoolThread::threadLoop (this=0x55b626aa00) at vendor/htc/native/libs/binder/ProcessState.cpp:65 #6 0x0000007f7e906b58 in android::Thread::_threadLoop (user=0x55b626aa00) at system/core/libutils/Threads.cpp:758 #7 0x0000007f7e74c474 in android::AndroidRuntime::javaThreadShell (args=<optimized out>) at frameworks/base/core/jni/AndroidRuntime.cpp:1320 #8 0x0000007f7e9062f4 in thread_data_t::trampoline (t=<optimized out>) at system/core/libutils/Threads.cpp:98 #9 0x0000007f7e552048 in __pthread_start (arg=0x7f79c46450, arg@entry=<error reading variable: value has been optimized out>) at bionic/libc/bionic/pthread_create.cpp:199 #10 0x0000007f7e504848 in __start_thread (fn=<optimized out>, arg=<optimized out>) at bionic/libc/bionic/clone.cpp:41 #11 0x0000000000000000 in ?? ()