Chromium Code Reviews| Index: build/android/pylib/symbols/elf_symbolizer.py |
| diff --git a/build/android/pylib/symbols/elf_symbolizer.py b/build/android/pylib/symbols/elf_symbolizer.py |
| index 90e99e5a2757770b30d8d3a89d0a34b589212780..25ae1a9f864fdf9c29242a582d6ad32195b08d68 100644 |
| --- a/build/android/pylib/symbols/elf_symbolizer.py |
| +++ b/build/android/pylib/symbols/elf_symbolizer.py |
| @@ -184,6 +184,13 @@ class ELFSymbolizer(object): |
| # separate field because turned out to be a perf hot-spot. |
| self.queue_size = 0 |
| + # Keep track of requests count so that we can replace addr2line |
| + # processes before they consume all the memory of the machine |
| + # and become slow and evil. |
| + self._max_requests_per_process = 1000 |
|
Andrew Hayden (chromium.org)
2014/05/30 15:42:29
I think I left out a zero. I want to say this was
Primiano Tucci (use gerrit)
2014/05/30 16:56:20
Two notes:
You eventually want to make this an arg
Daniel Bratell
2014/06/04 15:31:16
I did some measurements at my computer. It becomes
Daniel Bratell
2014/06/04 15:31:16
You were right, 1000 was too small. See measuremen
|
| + self._queued_request_count = 0 |
|
Primiano Tucci (use gerrit)
2014/05/30 16:56:20
You just need one "counter" variable, not two (see
|
| + self._received_answer_count = 0 |
| + |
| # Objects required to handle the addr2line subprocess. |
| self._proc = None # Subprocess.Popen(...) instance. |
| self._thread = None # Threading.thread instance. |
| @@ -196,7 +203,10 @@ class ELFSymbolizer(object): |
| req_idx = self._symbolizer.requests_counter |
| self._request_queue.append((addr, callback_arg, req_idx)) |
| self.queue_size += 1 |
| - self._WriteToA2lStdin(addr) |
| + self._queued_request_count += 1 |
|
Primiano Tucci (use gerrit)
2014/05/30 16:56:20
This extra logic here is unnecessary.
You can jus
|
| + if self._queued_request_count <= self._max_requests_per_process: |
| + # Otherwise they will be written once we restart the process. |
| + self._WriteToA2lStdin(addr) |
| def WaitForIdle(self): |
| """Waits until all the pending requests have been symbolized.""" |
| @@ -215,6 +225,13 @@ class ELFSymbolizer(object): |
| # The inner loop guards against a2l crashing (checking if it exited). |
| while (datetime.datetime.now() - start_time < timeout): |
| + # Restart the addr2line process if it has been running for a |
| + # while. It keeps growing so otherwise it will make the |
| + # whole computer unresponsive, including itself. |
| + if self._received_answer_count >= self._max_requests_per_process: |
| + self._queued_request_count -= self._received_answer_count |
|
Primiano Tucci (use gerrit)
2014/05/30 16:56:20
This math seems rendudant.
Here you just want to k
Daniel Bratell
2014/06/04 15:31:16
Seems it became a little bit faster by this change
|
| + self._received_answer_count = 0 |
| + self._RestartAddr2LineProcess() |
| # poll() returns !None if the process exited. a2l should never exit. |
| if self._proc.poll(): |
| logging.warning('addr2line crashed, respawning (lib: %s).' % |
| @@ -297,6 +314,7 @@ class ELFSymbolizer(object): |
| if not innermost_sym_info: |
| innermost_sym_info = sym_info |
| + self._received_answer_count += 1 |
| self._symbolizer.callback(innermost_sym_info, callback_arg) |
| def _RestartAddr2LineProcess(self): |