1.. _module-pw_symbolizer: 2 3============= 4pw_symbolizer 5============= 6.. pigweed-module:: 7 :name: pw_symbolizer 8 9.. warning:: 10 This module is under construction and may not be ready for use. 11 12pw_symbolizer provides python-based tooling for symbolizing addresses emitted by 13on-device firmware. 14 15----- 16Usage 17----- 18Symbolizer 19========== 20The ``Symbolizer`` abstract base class is an interface for translating addresses 21to human-readable source locations. Different architectures and operating 22systems can require vastly different implementations, so this interface is 23provided to allow Pigweed tooling to symbolize addresses without requiring 24Pigweed to provide explicit support for all possible implementations. 25 26``Symbolizer`` Also provides a helper function for producing nicely formatted 27stack trace style dumps. 28 29.. code-block:: py 30 31 import pw_symbolizer 32 33 symbolizer = pw_symbolizer.LlvmSymbolizer(Path('device_fw.elf')) 34 print(symbolizer.dump_stack_trace(backtrace_addresses)) 35 36Which produces output like this: 37 38.. code-block:: none 39 40 Stack Trace (most recent call first): 41 1: at device::system::logging_thread_context (0x08004BE0) 42 in threads.cc:0 43 2: at device::system::logging_thread (0x0800B508) 44 in ??:? 45 3: at device::system::logging_thread_context (0x08004CB8) 46 in threads.cc:0 47 4: at device::system::logging_thread (0x0800B3C0) 48 in ??:? 49 5: at device::system::logging_thread (0x0800B508) 50 in ??:? 51 6: at (0x0800BAF7) 52 in ??:? 53 7: at common::log::LoggingThread::Run() (0x0800BAD1) 54 in out/common/log/logging_thread.cc:26 55 8: at pw::thread::threadx::Context::ThreadEntryPoint(unsigned long) (0x0800539D) 56 in out/pigweed/pw_thread_threadx/thread.cc:41 57 9: at device::system::logging_thread_context (0x08004CB8) 58 in threads.cc:0 59 10: at device::system::logging_thread_context (0x08004BE0) 60 in threads.cc:0 61 62FakeSymbolizer 63============== 64The ``FakeSymbolizer`` is utility class that implements the ``Symbolizer`` 65interface with a fixed database of address to ``Symbol`` mappings. This is 66useful for testing, or as a no-op ``Symbolizer``. 67 68.. code-block:: py 69 70 import pw_symbolizer 71 72 known_symbols = ( 73 pw_symbolizer.Symbol(0x0800A200, 'foo()', 'src/foo.c', 41), 74 pw_symbolizer.Symbol(0x08000004, 'boot_entry()', 'src/vector_table.c', 5), 75 ) 76 symbolizer = pw_symbolizer.FakeSymbolizer(known_symbols) 77 sym = symbolizer.symbolize(0x0800A200) 78 print(f'This fake symbolizer knows about: {sym}') 79 80LlvmSymbolizer 81============== 82The ``LlvmSymbolizer`` is a python layer that wraps ``llvm-symbolizer`` to 83produce symbols from provided addresses. This module requires either: 84 85* ``llvm-symbolizer`` is available on the system ``PATH``. 86* ``llvm_symbolizer_binary`` argument is specified and points to the executable. 87 88This object also defines a ``close`` to ensure the background process is 89cleaned up deterministically. 90 91.. code-block:: py 92 93 import pw_symbolizer 94 95 symbolizer = pw_symbolizer.LlvmSymbolizer(Path('device_fw.elf')) 96 sym = symbolizer.symbolize(0x2000ac21) 97 print(f'You have a bug here: {sym}') 98