1

This is sister-question of How to find load relocation for a PIE binary? which was solved by using _r_debug.r_map->l_addr. Now I need to do this on Android NDK 19.

I need to print backtrace without symbols. I can do this with following code:

#include <iostream>
#include <iomanip>
#include <unwind.h>
#include <dlfcn.h>
#include <sstream>
#include <android/log.h>


namespace {

struct BacktraceState
{
    void** current;
    void** end;
};

static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg)
{
    BacktraceState* state = static_cast<BacktraceState*>(arg);
    uintptr_t pc = _Unwind_GetIP(context);
    if (pc) {
        if (state->current == state->end) {
            return _URC_END_OF_STACK;
        } else {
            *state->current++ = reinterpret_cast<void*>(pc);
        }
    }
    return _URC_NO_REASON;
}

}

size_t captureBacktrace(void** buffer, size_t max)
{
    BacktraceState state = {buffer, buffer + max};
    _Unwind_Backtrace(unwindCallback, &state);

    return state.current - buffer;
}

namespace clog {

std::string bt(int from, int max_stack) {

    const size_t MAX_STACK = 30;

    if (from >= max_stack)
        from = 0;
    if (max_stack > MAX_STACK)
        max_stack = MAX_STACK;

    void* array[MAX_STACK];
    std::ostringstream msg;

    size_t size = captureBacktrace(array, MAX_STACK);
    if (size >= 2) {
        msg << "[bt]" << std::hex;
        for (int i = from; i < size; ++i) {
            msg << "0x" << reinterpret_cast<uintptr_t>(array[i]) << " ";
        }
        msg << "[/bt]" << std::dec;
    }
    return msg.str();
}
}

It prints addresses that include offset from ASLR. On Linux I fixed this by changing

msg << "0x" << reinterpret_cast<uintptr_t>(array[i]) << " ";

to

#include <execinfo.h>
#include <link.h>
...
static const uintptr_t relocation = _r_debug.r_map->l_addr;
msg << "0x" << reinterpret_cast<uintptr_t>(array[i]) - reinterpret_cast<uintptr_t>(relocation) << " ";

_r_debug.r_map->l_addr is not available on Android as far as I can see. Is there some equivalent?

MateuszL
  • 2,751
  • 25
  • 38

0 Answers0