c - HOWTO get the correct Frame Pointer of an arbitrary thread in iOS? -


way frame pointer

enter image description here

on demo app running on iphone 5s device / xcode 7, tried frame pointer of arbitrary thread using thread_get_state , result in incorrect 1 :

- (bool)fillthreadstate:(thread_t)thread intomachinecontext:(_struct_mcontext *)machinecontext {     mach_msg_type_number_t state_count = machine_thread_state_count;     kern_return_t kr = thread_get_state(thread, machine_thread_state, (thread_state_t)&machinecontext->__ss, &state_count);     if (kr != kern_success) {         char *str = mach_error_string(kr);         printf("%s\n", str);         return no;     }      return yes; } 

i read frame pointer this: uintptr_t fp = machinecontext.__ss.__fp;, according apple doc (armv6 , arm64),

register r7 used frame pointer on armv6

while x29 on arm64

the frame pointer register (x29) must address valid frame record, although functions—such leaf functions or tail calls—may elect not create entry in list. result, stack traces meaningful, without debug information.

_struct_arm_thread_state64 {     __uint64_t    __x[29];  /* general purpose registers x0-x28 */     __uint64_t    __fp;     /* frame pointer x29 */     __uint64_t    __lr;     /* link register x30 */     __uint64_t    __sp;     /* stack pointer x31 */     __uint64_t    __pc;     /* program counter */     __uint32_t    __cpsr;   /* current program status register */     __uint32_t    __pad;    /* same size 32-bit or 64-bit clients */ }; 

way prove frame pointer wrong

how prove fp (machinecontext.__ss.__fp) not correct frame pointer?

  1. if parameter current thread, mach_thread_self() example, fp 0, different __builtin_frame_address(0);

  2. if parameter not current thread, main thread example, pointer previous frame pointer of fp null in 2 or 3 frames, short normal link-list of stack frames;

  3. still not current thread, print out call stack addresses using backtrace on main thread before sleep. on thread, suspend main thread , read frame pointer using thread_get_state walk call stack, 2 backtrace buffers totally different;

what confuses me

apple doc says the frame pointer register (x29) must address valid frame record, read zero value it.

furthermore, arm doc states in variants of procedure call standard, registers r16, r17, r29 , r30 have special roles. in these roles labeled ip0, ip1, fp , lr when being used holding addresses.

below example of part of _struct_mcontext's value:

printing description of machinecontext: (__darwin_mcontext64) machinecontext = {   __es = (__far = 0, __esr = 0, __exception = 0)   __ss = {     __x = {       [0] = 292057776134       [1] = 6142843584       [2] = 3       [3] = 40       [4] = 624       [5] = 17923       [6] = 0       [7] = 0       [8] = 3968       [9] = 4294966207       [10] = 3603       [11] = 70       [12] = 0       [13] = 33332794515418112       [14] = 0       [15] = 4294967295       [16] = 4294967284       [17] = 18446744073709551585       [18] = 4295035980       [19] = 0       [20] = 0       [21] = 0       [22] = 17923       [23] = 624       [24] = 6142843584       [25] = 3       [26] = 40       [27] = 3       [28] = 0     }     __fp = 0     __lr = 6142843568     __sp = 6877072044     __pc = 6142843488     __cpsr = 2582105136     __pad = 1   }   __ns = { 

what looking for

i'm searching method correct value of frame pointer of arbitrary thread.

thanks help!

update 1

of course, want correct frame pointer of leaf stack frame of arbitrary thread, , walk call stack along previous pointer of frame pointer.

before this, i've read these links:

getting backtrace of other thread

how loop through active thread in ipad app

printing stack trace thread

thanks again.

update 2

i've tried on other platforms, yet same result : wrong frame pointer.

- (uintptr_t)framepointerofmachinecontext:(_struct_mcontext *)machinecontext { #if defined (__i386__)     return machinecontext->__ss.__ebp; #endif  #if defined (__x86_64__)     return machinecontext->__ss.__rbp; #endif  #if defined (__arm64__)     return machinecontext->__ss.__fp; #endif } 

the value framepointerofmachinecontext returns not same __builtin_frame_address(0).

update 3

inspired colleague, tried inline asm , made on i386:

uintptr_t ebp = 1; __asm__ ("mov %%ebp, %0;"          :"=r"(ebp));  uintptr_t builtinfp = (uintptr_t)__builtin_frame_address(0); 

now ebp variable holds same value builtinfp's. howto on arbitrary thread?

i found problem eventually,

- (bool)fillthreadstate:(thread_t)thread intomachinecontext:(_struct_mcontext *)machinecontext {     mach_msg_type_number_t state_count = machine_thread_state_count;     kern_return_t kr = thread_get_state(thread, machine_thread_state, (thread_state_t)&machinecontext->__ss, &state_count);     if (kr != kern_success) {         char *str = mach_error_string(kr);         printf("%s\n", str);         return no;     }      return yes; } 

thread_get_state fine, parameter should architecture-specific, such x86_thread_state32, x86_thread_state64 , etc.

i misunderstood macro machine_thread_state, gave me universal meaning different architectures.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

android - Go back to previous fragment -