1#include <Common/SymbolIndex.h>
2#include <Common/Elf.h>
3#include <Common/Dwarf.h>
4#include <Core/Defines.h>
5#include <common/demangle.h>
6#include <iostream>
7#include <dlfcn.h>
8
9#pragma GCC diagnostic push
10#pragma GCC diagnostic ignored "-Wunused-function"
11static NO_INLINE const void * getAddress()
12{
13 return __builtin_return_address(0);
14}
15#pragma GCC diagnostic pop
16
17int main(int argc, char ** argv)
18{
19#if defined(__ELF__) && !defined(__FreeBSD__)
20 using namespace DB;
21
22 if (argc < 2)
23 {
24 std::cerr << "Usage: ./symbol_index address\n";
25 return 1;
26 }
27
28 const SymbolIndex & symbol_index = SymbolIndex::instance();
29
30 for (const auto & elem : symbol_index.symbols())
31 std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n";
32 std::cout << "\n";
33
34 const void * address = reinterpret_cast<void*>(std::stoull(argv[1], nullptr, 16));
35
36 auto symbol = symbol_index.findSymbol(address);
37 if (symbol)
38 std::cerr << symbol->name << ": " << symbol->address_begin << " ... " << symbol->address_end << "\n";
39 else
40 std::cerr << "SymbolIndex: Not found\n";
41
42 Dl_info info;
43 if (dladdr(address, &info) && info.dli_sname)
44 std::cerr << demangle(info.dli_sname) << ": " << info.dli_saddr << "\n";
45 else
46 std::cerr << "dladdr: Not found\n";
47
48 auto object = symbol_index.findObject(getAddress());
49 Dwarf dwarf(*object->elf);
50
51 Dwarf::LocationInfo location;
52 if (dwarf.findAddress(uintptr_t(address) - uintptr_t(info.dli_fbase), location, Dwarf::LocationInfoMode::FAST))
53 std::cerr << location.file.toString() << ":" << location.line << "\n";
54 else
55 std::cerr << "Dwarf: Not found\n";
56
57 std::cerr << "\n";
58 std::cerr << StackTrace().toString() << "\n";
59#else
60 (void)argc;
61 (void)argv;
62
63 std::cerr << "This test does not make sense for non-ELF objects.\n";
64#endif
65
66 return 0;
67}
68