Skip to content
Snippets Groups Projects
Commit 1b926676 authored by David Garibaldi's avatar David Garibaldi
Browse files

lrdpv2: Ensure that QTF parsing is thread-safe

The debug_image_v2 module's usage of QTF to extract Ftrace log
information currently relies on a single QTF server process, and
communicates with that server process via a fixed port ID. Any other
instances of the ramdump parser running in parallel will also use
this same server and port ID, which presents a race condition if
multiple instances attempt to parse QTF input files simultaneously.

To deal with this problem, each ramdump parser instance must instead
create and communicate with its own QTF server process via a unique
port ID.

Change-Id: Ic9c53003789dca229d1e2770d01aa15a702292a7
parent a025f637
No related branches found
No related tags found
No related merge requests found
...@@ -15,8 +15,10 @@ import re ...@@ -15,8 +15,10 @@ import re
import shutil import shutil
import os import os
import platform import platform
import random
import subprocess import subprocess
import sys import sys
import time
from dcc import DccRegDump, DccSramDump from dcc import DccRegDump, DccSramDump
from pmic import PmicRegDump from pmic import PmicRegDump
...@@ -288,14 +290,38 @@ class DebugImage_v2(): ...@@ -288,14 +290,38 @@ class DebugImage_v2():
else: else:
return return
port = 12345 port = None
server_proc = None
qtf_success = False
max_tries = 3
qtf_dir = os.path.join(out_dir, 'qtf') qtf_dir = os.path.join(out_dir, 'qtf')
workspace = os.path.join(qtf_dir, 'qtf.workspace') workspace = os.path.join(qtf_dir, 'qtf.workspace')
qtf_out = os.path.join(out_dir, 'qtf.txt') qtf_out = os.path.join(out_dir, 'qtf.txt')
chipset = 'msm' + str(ram_dump.hw_id) chipset = 'msm' + str(ram_dump.hw_id)
hlos = 'LA' hlos = 'LA'
p = subprocess.Popen([qtf_path, '-s', '{0}'.format(port)]) # Resolve any port collisions with other running qtf_server instances
for tries in range(max_tries):
port = random.randint(12000, 13000)
server_proc = subprocess.Popen(
[qtf_path, '-s', '{0}'.format(port)], stderr=subprocess.PIPE)
time.sleep(1)
server_proc.poll()
if server_proc.returncode == 1:
server_proc.terminate()
continue
else:
qtf_success = True
break
if not qtf_success:
server_proc.terminate()
print_out_str('!!! Could not open a QTF server instance with a '
'unique port (last port tried: '
'{0})'.format(str(port)))
print_out_str('!!! Please kill all currently running qtf_server '
'processes and try again')
return
subprocess.call('{0} -c {1} new workspace {2} {3} {4}'.format(qtf_path, port, qtf_dir, chipset, hlos)) subprocess.call('{0} -c {1} new workspace {2} {3} {4}'.format(qtf_path, port, qtf_dir, chipset, hlos))
self.collect_ftrace_format(ram_dump) self.collect_ftrace_format(ram_dump)
...@@ -303,8 +329,9 @@ class DebugImage_v2(): ...@@ -303,8 +329,9 @@ class DebugImage_v2():
subprocess.call('{0} -c {1} open workspace {2}'.format(qtf_path, port, workspace)) subprocess.call('{0} -c {1} open workspace {2}'.format(qtf_path, port, workspace))
subprocess.call('{0} -c {1} open bin {2}'.format(qtf_path, port, trace_file)) subprocess.call('{0} -c {1} open bin {2}'.format(qtf_path, port, trace_file))
subprocess.call('{0} -c {1} stream trace table {2}'.format(qtf_path, port, qtf_out)) subprocess.call('{0} -c {1} stream trace table {2}'.format(qtf_path, port, qtf_out))
subprocess.call('{0} -c {1} close'.format(qtf_path, port))
subprocess.call('{0} -c {1} exit'.format(qtf_path, port)) subprocess.call('{0} -c {1} exit'.format(qtf_path, port))
p.communicate('quit') server_proc.communicate('quit')
def parse_dcc(self, ram_dump): def parse_dcc(self, ram_dump):
out_dir = ram_dump.outdir out_dir = ram_dump.outdir
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment