// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// N.B. The offline symbolizer (scripts/symbolize) reads our output,
// don't break it.

#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <backtrace/backtrace.h>

#include <ngunwind/libunwind.h>
#include <ngunwind/fuchsia.h>

#include <zircon/types.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>

#include <fbl/alloc_checker.h>
#include <fbl/array.h>

#include "inspector/inspector.h"
#include "dso-list-impl.h"
#include "utils-impl.h"

namespace inspector {

// Keep open debug info for this many files.
constexpr size_t kDebugInfoCacheNumWays = 2;

constexpr unsigned int kBacktraceFrameLimit = 50;

// Error callback for libbacktrace.

static void
bt_error_callback(void* vdata, const char* msg, int errnum) {
    fprintf(stderr, "%s", msg);
    if (errnum > 0)
        fprintf(stderr, ": %s", strerror (errnum));
    fprintf(stderr, "\n");
}

// backtrace_so_iterator function.
// We don't use libbacktrace to do the unwinding, we only use it to get
// file,line#,function_name for each pc. Therefore we don't need it to
// iterate over all shared libs.

static int
bt_so_iterator (void* iter_state, backtrace_so_callback* callback, void* data) {
    // Return non-zero so iteration stops.
    return 1;
}

// A cache of data stored for each shared lib.
// This lets us lazily obtain debug info, and only keep
// a subset of it in memory.
class DebugInfoCache {
 public:
    DebugInfoCache(inspector_dsoinfo_t* dso_list, size_t nr_ways);
    ~DebugInfoCache();

    inspector_dsoinfo_t* dso_list() { return dso_list_; }

    zx_status_t GetDebugInfo(uintptr_t pc, inspector_dsoinfo_t** out_dso,
                             backtrace_state** out_bt_state);

 private:
    inspector_dsoinfo_t* dso_list_;

    size_t last_used_ = 0;

    bool cache_avail_ = false;

    struct way {
        // Not owned by us. This is the "tag".
        inspector_dsoinfo_t* dso = nullptr;
        // Owned by us.
        backtrace_state* bt_state = nullptr;
    };

    fbl::Array<way> ways_;
};

// Note: We *do not* take ownership of |dso_list|.
// Its lifetime must survive ours.

DebugInfoCache::DebugInfoCache(inspector_dsoinfo_t* dso_list, size_t nr_ways)
    : dso_list_(dso_list) {
    fbl::AllocChecker ac;
    auto ways = new (&ac) way[nr_ways];
    if (!ac.check()) {
        debugf(1, "unable to initialize debug info cache\n");
        return;
    }
    ways_.reset(ways, nr_ways);
    cache_avail_ = true;
}

DebugInfoCache::~DebugInfoCache() {
    if (cache_avail_) {
        for (size_t i = 0; i < ways_.size(); ++i) {
            backtrace_destroy_state(ways_[i].bt_state, bt_error_callback, nullptr);
        }
    }
}

// Find the DSO and debug info (backtrace_state) for PC.
// Returns ZX_ERR_NOT_FOUND if |pc| is not in any DSO.
// Otherwise the result is ZX_OK, even if there is no extended debug
// info for libbacktrace (e.g., -g1 info).
// If the result is ZX_OK then |*out_dso| is set.
// If the result is ZX_OK then |*out_bt_state| is set to the
// accompanying libbacktrace state if available or nullptr if not.

zx_status_t DebugInfoCache::GetDebugInfo(uintptr_t pc,
                                         inspector_dsoinfo_t** out_dso,
                                         backtrace_state** out_bt_state) {
    inspector_dsoinfo_t* dso = inspector_dso_lookup(dso_list_, pc);
    if (dso == nullptr) {
        debugf(1, "No DSO found for pc %p\n", (void*) pc);
        return ZX_ERR_NOT_FOUND;
    }

#if 1 // Skip using libbacktrace until leaks are fixed. ZX-351
    *out_dso = dso;
    *out_bt_state = nullptr;
    return ZX_OK;
#endif

    // If we failed to initialize the cache (OOM) we can still report the
    // DSO we found.
    if (!cache_avail_) {
        *out_dso = dso;
        *out_bt_state = nullptr;
        return ZX_OK;
    }

    const size_t nr_ways = ways_.size();

    for (size_t i = 0; i < nr_ways; ++i) {
        if (ways_[i].dso == dso) {
            debugf(1, "using cached debug info entry for pc %p\n", (void*) pc);
            *out_dso = dso;
            *out_bt_state = ways_[i].bt_state;
            return ZX_OK;
        }
    }

    // PC is in a DSO, but not found in the cache.
    // N.B. From this point on the result is ZX_OK.
    // If there is an "error" the user can still print something (and there's
    // no point in having error messages pollute the backtrace, at least by
    // default).

    *out_dso = dso;
    *out_bt_state = nullptr;

    const char* debug_file = nullptr;
    auto status = inspector_dso_find_debug_file(dso, &debug_file);
    if (status != ZX_OK) {
        // There's no additional debug file available, but we did find the DSO.
        return ZX_OK;
    }

    struct backtrace_state* bt_state =
        backtrace_create_state(debug_file, 0 /*!threaded*/,
                               bt_error_callback, nullptr);
    if (bt_state == nullptr) {
        debugf(1, "backtrace_create_state failed (OOM)\n");
        return ZX_OK;
    }

    // last_used_+1: KISS until there's data warranting something better
    size_t way = (last_used_ + 1) % nr_ways;
    if (ways_[way].dso != nullptr) {
        // Free the entry.
        backtrace_destroy_state(ways_[way].bt_state, bt_error_callback, nullptr);
        ways_[way].dso = nullptr;
        ways_[way].bt_state = nullptr;
    }

    // The iterator doesn't do anything, but we pass |list| anyway
    // in case some day we need it to.
    backtrace_set_so_iterator(bt_state, bt_so_iterator, dso_list_);
    backtrace_set_base_address(bt_state, dso->base);

    ways_[way].dso = dso;
    ways_[way].bt_state = bt_state;
    *out_bt_state = bt_state;
    last_used_ = way;
    return ZX_OK;
}

// Data to pass back from backtrace_pcinfo.
// We don't use libbacktrace to print the backtrace, we only use it to
// obtain file,line#,function_name.

struct bt_pcinfo_data
{
    const char* filename;
    int lineno;
    const char* function;
};

// Callback invoked by libbacktrace.

static int
btprint_callback(void* vdata, uintptr_t pc, const char* filename, int lineno,
                  const char* function) {
    auto data = reinterpret_cast<bt_pcinfo_data*> (vdata);

    data->filename = filename;
    data->lineno = lineno;
    data->function = function;

    return 0;
}

static void btprint(FILE* f, DebugInfoCache* di_cache,
                    uint32_t n, uintptr_t pc, uintptr_t sp,
                    bool use_new_format) {
    if (use_new_format) {
        fprintf(f, "{{{bt:%u:%#" PRIxPTR "}}}\n", n, pc);
        return;
    }

    inspector_dsoinfo_t* dso;
    backtrace_state* bt_state;
    auto status = di_cache->GetDebugInfo(pc, &dso, &bt_state);

    if (status != ZX_OK) {
        // The pc is not in any DSO.
        fprintf(f, "bt#%02u: pc %p sp %p\n",
                n, (void*) pc, (void*) sp);
        return;
    }

    // Try to use libbacktrace if we can.

    struct bt_pcinfo_data pcinfo_data;
    memset(&pcinfo_data, 0, sizeof(pcinfo_data));

    if (bt_state != nullptr) {
        auto ret = backtrace_pcinfo(bt_state, pc, btprint_callback,
                                    bt_error_callback, &pcinfo_data);
        if (ret == 0) {
            // FIXME: How to interpret the result is seriously confusing.
            // There are cases where zero means failure and others where
            // zero means success. For now we just assume that pcinfo_data
            // will only be filled in on success.
        }
    }

    fprintf(f, "bt#%02u: pc %p sp %p (%s,%p)",
            n, (void*) pc, (void*) sp, dso->name, (void*) (pc - dso->base));
    if (pcinfo_data.filename != nullptr && pcinfo_data.lineno > 0) {
        const char* base = path_basename(pcinfo_data.filename);
        // Be paranoid and handle |pcinfo_data.filename| having a trailing /.
        // If so, just print the whole thing and let the user figure it out.
        if (*base == '\0')
            base = pcinfo_data.filename;
        fprintf(f, " %s:%d", base, pcinfo_data.lineno);
    }
    if (pcinfo_data.function != nullptr)
        fprintf(f, " %s", pcinfo_data.function);
    fprintf(f, "\n");
}

static int dso_lookup_for_unw(void* context, unw_word_t pc,
                              unw_word_t* base, const char** name) {
    auto dso_list = reinterpret_cast<inspector_dsoinfo_t*>(context);
    inspector_dsoinfo_t* dso = inspector_dso_lookup(dso_list, pc);
    if (dso == nullptr)
        return 0;
    *base = dso->base;
    *name = dso->name;
    return 1;
}

static
void inspector_print_backtrace_impl(FILE* f,
                                    zx_handle_t process, zx_handle_t thread,
                                    inspector_dsoinfo_t* dso_list,
                                    uintptr_t pc, uintptr_t sp, uintptr_t fp,
                                    bool use_libunwind,
                                    bool use_new_format) {
    // Set up libunwind if requested.

    bool libunwind_ok = use_libunwind;
    if (verbosity_level > 0) {
        // Don't turn on libunwind debugging for -d1.
        // Note: max libunwind debugging level is 16
        unw_set_debug_level(verbosity_level - 1);
    }

    unw_fuchsia_info_t* fuchsia = nullptr;
    unw_addr_space_t remote_as = nullptr;

    if (libunwind_ok) {
        fuchsia = unw_create_fuchsia(process, thread, dso_list, dso_lookup_for_unw);
        if (fuchsia == nullptr)
        {
            print_error("unw_fuchsia_create failed (OOM)");
            libunwind_ok = false;
        }
    }

    if (libunwind_ok) {
        remote_as =
            unw_create_addr_space((unw_accessors_t*) &_UFuchsia_accessors, 0);
        if (remote_as == nullptr)
        {
            print_error("unw_create_addr_space failed (OOM)");
            libunwind_ok = false;
        }
    }

    unw_cursor_t cursor;
    if (libunwind_ok) {
        int ret = unw_init_remote(&cursor, remote_as, fuchsia);
        if (ret < 0) {
            print_error("unw_init_remote failed (%d)", ret);
            libunwind_ok = false;
        }
    }

    if (!libunwind_ok) {
        print_error("Unable to initialize libunwind.");
        print_error("Falling back on heuristics which likely won't work");
        print_error("with optimized code.");
    }

    // TODO: Handle libunwind not finding .eh_frame in which case fallback
    // on using heuristics. Ideally this would be handled on a per-DSO basis.

    // Keep a cache of loaded debug info to maintain some performance
    // without loading debug info for all shared libs.
    // This won't get used if initializing libunwind failed, but we can still
    // use |dso_list|.
    DebugInfoCache di_cache(dso_list, kDebugInfoCacheNumWays);

    // On with the show.

    uint32_t n = 1;
    btprint(f, &di_cache, n++, pc, sp, use_new_format);
    while ((sp >= 0x1000000) && (n < kBacktraceFrameLimit)) {
        if (libunwind_ok) {
            int ret = unw_step(&cursor);
            if (ret < 0) {
                print_error("unw_step failed for pc %p, aborting backtrace here",
                            (void*) pc);
                break;
            }
            if (ret == 0)
                break;
            unw_word_t val;
            unw_get_reg(&cursor, UNW_REG_IP, &val);
            pc = val;
            unw_get_reg(&cursor, UNW_REG_SP, &val);
            sp = val;
        } else {
            sp = fp;
            if (read_mem(process, fp + 8, &pc, sizeof(pc))) {
                break;
            }
            if (read_mem(process, fp, &fp, sizeof(fp))) {
                break;
            }
        }
        btprint(f, &di_cache, n++, pc, sp, use_new_format);
    }

    if (!use_new_format) {
        fprintf(f, "bt#%02d: end\n", n);
    }

    if (n >= kBacktraceFrameLimit) {
        fprintf(f, "warning: backtrace frame limit exceeded; backtrace may be truncated\n");
    }

    unw_destroy_addr_space(remote_as);
    unw_destroy_fuchsia(fuchsia);
}

extern "C" __EXPORT
void inspector_print_backtrace_markup(FILE* f,
                                      zx_handle_t process, zx_handle_t thread,
                                      inspector_dsoinfo_t* dso_list,
                                      uintptr_t pc, uintptr_t sp, uintptr_t fp,
                                      bool use_libunwind) {
    inspector_print_backtrace_impl(f, process, thread, dso_list, pc, sp, fp,
                                  use_libunwind, true);
}

extern "C" __EXPORT
void inspector_print_backtrace(FILE* f,
                               zx_handle_t process, zx_handle_t thread,
                               inspector_dsoinfo_t* dso_list,
                               uintptr_t pc, uintptr_t sp, uintptr_t fp,
                               bool use_libunwind) {
    inspector_print_backtrace_impl(f, process, thread, dso_list, pc, sp, fp,
                                  use_libunwind, false);
}

}  // namespace inspector
