Flutter Engine
The Flutter Engine
|
Classes | |
class | Addr2Line |
Public Member Functions | |
def | __init__ (self, elf_file_path, addr2line_path, callback, inlines=False, max_concurrent_jobs=None, addr2line_timeout=30, max_queue_size=50, source_root_path=None, strip_base_path=None) |
def | SymbolizeAsync (self, addr, callback_arg=None) |
def | Join (self) |
An uber-fast (multiprocessing, pipelined and asynchronous) ELF symbolizer. This class is a frontend for addr2line (part of GNU binutils), designed to symbolize batches of large numbers of symbols for a given ELF file. It supports sharding symbolization against many addr2line instances and pipelining of multiple requests per each instance (in order to hide addr2line internals and OS pipe latencies). The interface exhibited by this class is a very simple asynchronous interface, which is based on the following three methods: - SymbolizeAsync(): used to request (enqueue) resolution of a given address. - The |callback| method: used to communicated back the symbol information. - Join(): called to conclude the batch to gather the last outstanding results. In essence, before the Join method returns, this class will have issued as many callbacks as the number of SymbolizeAsync() calls. In this regard, note that due to multiprocess sharding, callbacks can be delivered out of order. Some background about addr2line: - it is invoked passing the elf path in the cmdline, piping the addresses in its stdin and getting results on its stdout. - it has pretty large response times for the first requests, but it works very well in streaming mode once it has been warmed up. - it doesn't scale by itself (on more cores). However, spawning multiple instances at the same time on the same file is pretty efficient as they keep hitting the pagecache and become mostly CPU bound. - it might hang or crash, mostly for OOM. This class deals with both of these problems. Despite the "scary" imports and the multi* words above, (almost) no multi- threading/processing is involved from the python viewpoint. Concurrency here is achieved by spawning several addr2line subprocesses and handling their output pipes asynchronously. Therefore, all the code here (with the exception of the Queue instance in Addr2Line) should be free from mind-blowing thread-safety concerns. The multiprocess sharding works as follows: The symbolizer tries to use the lowest number of addr2line instances as possible (with respect of |max_concurrent_jobs|) and enqueue all the requests in a single addr2line instance. For few symbols (i.e. dozens) sharding isn't worth the startup cost. The multiprocess logic kicks in as soon as the queues for the existing instances grow. Specifically, once all the existing instances reach the |max_queue_size| bound, a new addr2line instance is kicked in. In the case of a very eager producer (i.e. all |max_concurrent_jobs| instances have a backlog of |max_queue_size|), back-pressure is applied on the caller by blocking the SymbolizeAsync method. This module has been deliberately designed to be dependency free (w.r.t. of other modules in this project), to allow easy reuse in external projects.
Definition at line 25 of file elf_symbolizer.py.
def elf_symbolizer.ELFSymbolizer.__init__ | ( | self, | |
elf_file_path, | |||
addr2line_path, | |||
callback, | |||
inlines = False , |
|||
max_concurrent_jobs = None , |
|||
addr2line_timeout = 30 , |
|||
max_queue_size = 50 , |
|||
source_root_path = None , |
|||
strip_base_path = None |
|||
) |
Args: elf_file_path: path of the elf file to be symbolized. addr2line_path: path of the toolchain's addr2line binary. callback: a callback which will be invoked for each resolved symbol with the two args (sym_info, callback_arg). The former is an instance of |ELFSymbolInfo| and contains the symbol information. The latter is an embedder-provided argument which is passed to SymbolizeAsync(). inlines: when True, the ELFSymbolInfo will contain also the details about the outer inlining functions. When False, only the innermost function will be provided. max_concurrent_jobs: Max number of addr2line instances spawned. Parallelize responsibly, addr2line is a memory and I/O monster. max_queue_size: Max number of outstanding requests per addr2line instance. addr2line_timeout: Max time (in seconds) to wait for a addr2line response. After the timeout, the instance will be considered hung and respawned. source_root_path: In some toolchains only the name of the source file is is output, without any path information; disambiguation searches through the source directory specified by |source_root_path| argument for files whose name matches, adding the full path information to the output. For example, if the toolchain outputs "unicode.cc" and there is a file called "unicode.cc" located under |source_root_path|/foo, the tool will replace "unicode.cc" with "|source_root_path|/foo/unicode.cc". If there are multiple files with the same name, disambiguation will fail because the tool cannot determine which of the files was the source of the symbol. strip_base_path: Rebases the symbols source paths onto |source_root_path| (i.e replace |strip_base_path| with |source_root_path).
Definition at line 77 of file elf_symbolizer.py.
def elf_symbolizer.ELFSymbolizer.Join | ( | self | ) |
Waits for all the outstanding requests to complete and terminates.
Definition at line 181 of file elf_symbolizer.py.
def elf_symbolizer.ELFSymbolizer.SymbolizeAsync | ( | self, | |
addr, | |||
callback_arg = None |
|||
) |
Requests symbolization of a given address. This method is not guaranteed to return immediately. It generally does, but in some scenarios (e.g. all addr2line instances have full queues) it can block to create back-pressure. Args: addr: address to symbolize. callback_arg: optional argument which will be passed to the |callback|.
Definition at line 139 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.addr2line_path |
Definition at line 117 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.addr2line_timeout |
Definition at line 123 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.callback |
Definition at line 118 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.disambiguate |
Definition at line 128 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.disambiguation_table |
Definition at line 129 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.elf_file_path |
Definition at line 116 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.inlines |
Definition at line 119 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.max_concurrent_jobs |
Definition at line 120 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.max_queue_size |
Definition at line 122 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.requests_counter |
Definition at line 124 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.source_root_path |
Definition at line 132 of file elf_symbolizer.py.
elf_symbolizer.ELFSymbolizer.strip_base_path |
Definition at line 130 of file elf_symbolizer.py.