예제 #1
0
void get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames,
        backtrace_symbol_t* backtrace_symbols) {
    map_info_t* milist = acquire_my_map_info_list();
    for (size_t i = 0; i < frames; i++) {
        const backtrace_frame_t* frame = &backtrace[i];
        backtrace_symbol_t* symbol = &backtrace_symbols[i];
        init_backtrace_symbol(symbol, frame->absolute_pc);

        const map_info_t* mi = find_map_info(milist, frame->absolute_pc);
        if (mi) {
            symbol->relative_pc = frame->absolute_pc - mi->start;
            if (mi->name[0]) {
                symbol->map_name = strdup(mi->name);
            }
            Dl_info info;
            if (dladdr((const void*)frame->absolute_pc, &info) && info.dli_sname) {
                symbol->relative_symbol_addr = (uintptr_t)info.dli_saddr
                        - (uintptr_t)info.dli_fbase;
                symbol->symbol_name = strdup(info.dli_sname);
                symbol->demangled_name = demangle_symbol_name(symbol->symbol_name);
            }
        }
    }
    release_my_map_info_list(milist);
}
예제 #2
0
void find_symbol_ptrace(const ptrace_context_t* context,
        uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol) {
    const map_info_t* mi = find_map_info(context->map_info_list, addr);
    const symbol_t* symbol = NULL;
    if (mi) {
        const map_info_data_t* data = (const map_info_data_t*)mi->data;
        if (data && data->symbol_table) {
            symbol = find_symbol(data->symbol_table, addr - mi->start);
        }
    }
    *out_map_info = mi;
    *out_symbol = symbol;
}
예제 #3
0
파일: main.c 프로젝트: mike-kang/CallStack
int try_get_word(const mapinfo* map_info_list, uintptr_t ptr, uint32_t* out_value) {
    //ALOGV("try_get_word: reading word at 0x%08x", ptr);
    if (ptr & 3) {
        //ALOGV("try_get_word: invalid pointer 0x%08x", ptr);
        *out_value = 0xffffffffL;
        return 0;
    }
    //if (!is_readable_map(map_info_list, ptr)) {
        //ALOGV("try_get_word: pointer 0x%08x not in a readable map", ptr);
     //   *out_value = 0xffffffffL;
     //   return 0;
    //}
    if (!find_map_info(map_info_list, ptr)) {
        //ALOGV("try_get_word: pointer 0x%08x not in a readable map", ptr);
        *out_value = 0xffffffffL;
        return 0;
    }
    *out_value = *(uint32_t*)ptr;
    return 1;
}
예제 #4
0
bool is_executable_map(const map_info_t* milist, uintptr_t addr) {
    const map_info_t* mi = find_map_info(milist, addr);
    return mi && mi->is_executable;
}
예제 #5
0
static uintptr_t get_exception_handler(const memory_t* memory,
        const map_info_t* map_info_list, uintptr_t pc) {
    if (!pc) {
        ALOGV("get_exception_handler: pc is zero, no handler");
        return 0;
    }

    uintptr_t exidx_start;
    size_t exidx_size;
    const map_info_t* mi;
    if (memory->tid < 0) {
        mi = NULL;
        exidx_start = find_exidx(pc, &exidx_size);
    } else {
        mi = find_map_info(map_info_list, pc);
        if (mi && mi->data) {
            const map_info_data_t* data = (const map_info_data_t*)mi->data;
            exidx_start = data->exidx_start;
            exidx_size = data->exidx_size;
        } else {
            exidx_start = 0;
            exidx_size = 0;
        }
    }

    uintptr_t handler = 0;
    int32_t handler_index = -1;
    if (exidx_start) {
        uint32_t low = 0;
        uint32_t high = exidx_size;
        while (low < high) {
            uint32_t index = (low + high) / 2;
            uintptr_t entry = exidx_start + index * 8;
            uint32_t entry_prel_pc;
            ALOGV("XXX low=%u, high=%u, index=%u", low, high, index);
            if (!try_get_word(memory, entry, &entry_prel_pc)) {
                break;
            }
            uintptr_t entry_pc = prel_to_absolute(entry, entry_prel_pc);
            ALOGV("XXX entry_pc=0x%08x", entry_pc);
            if (pc < entry_pc) {
                high = index;
                continue;
            }
            if (index + 1 < exidx_size) {
                uintptr_t next_entry = entry + 8;
                uint32_t next_entry_prel_pc;
                if (!try_get_word(memory, next_entry, &next_entry_prel_pc)) {
                    break;
                }
                uintptr_t next_entry_pc = prel_to_absolute(next_entry, next_entry_prel_pc);
                ALOGV("XXX next_entry_pc=0x%08x", next_entry_pc);
                if (pc >= next_entry_pc) {
                    low = index + 1;
                    continue;
                }
            }

            uintptr_t entry_handler_ptr = entry + 4;
            uint32_t entry_handler;
            if (!try_get_word(memory, entry_handler_ptr, &entry_handler)) {
                break;
            }
            if (entry_handler & (1L << 31)) {
                handler = entry_handler_ptr; // in-place handler data
            } else if (entry_handler != EXIDX_CANTUNWIND) {
                handler = prel_to_absolute(entry_handler_ptr, entry_handler);
            }
            handler_index = index;
            break;
        }
    }
    if (mi) {
        ALOGV("get_exception_handler: pc=0x%08x, module='%s', module_start=0x%08x, "
                "exidx_start=0x%08x, exidx_size=%d, handler=0x%08x, handler_index=%d",
                pc, mi->name, mi->start, exidx_start, exidx_size, handler, handler_index);
    } else {
        ALOGV("get_exception_handler: pc=0x%08x, "
                "exidx_start=0x%08x, exidx_size=%d, handler=0x%08x, handler_index=%d",
                pc, exidx_start, exidx_size, handler, handler_index);
    }
    return handler;
}