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): |