Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: mojo/devtools/common/android_gdb/session.py

Issue 1253573008: Only update symbols on current thread when breaking or stepping in GDB. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Fix wording Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/devtools/common/README.md ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """ 5 """
6 Manages a debugging session with GDB. 6 Manages a debugging session with GDB.
7 7
8 This module is meant to be imported from inside GDB. Once loaded, the 8 This module is meant to be imported from inside GDB. Once loaded, the
9 |DebugSession| attaches GDB to a running Mojo Shell process on an Android 9 |DebugSession| attaches GDB to a running Mojo Shell process on an Android
10 device using a remote gdbserver. 10 device using a remote gdbserver.
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 # This library file is not known locally. Download it from the device or 183 # This library file is not known locally. Download it from the device or
184 # the cloud and put it in cache so, if it got symbols, we can see them. 184 # the cloud and put it in cache so, if it got symbols, we can see them.
185 local_file = os.path.join(self._remote_file_cache, signature) 185 local_file = os.path.join(self._remote_file_cache, signature)
186 if not os.path.exists(local_file): 186 if not os.path.exists(local_file):
187 tmp_output = self._download_file(signature, remote_file) 187 tmp_output = self._download_file(signature, remote_file)
188 shutil.move(tmp_output, local_file) 188 shutil.move(tmp_output, local_file)
189 self._associate_symbols(mapping, local_file) 189 self._associate_symbols(mapping, local_file)
190 return True 190 return True
191 return False 191 return False
192 192
193 def _update_symbols(self): 193 def _find_mappings_current_thread(self, mapped_files):
ppi 2015/07/23 23:08:31 this method is called "find", but doesn't return a
etiennej 2015/07/23 23:21:03 Changed the method name.
194 frame = gdb.newest_frame()
195 while frame and frame.is_valid():
196 if frame.name() is None:
197 m = self._find_mapping_for_address(mapped_files, frame.pc())
198 if m is not None and self._try_to_map(m):
199 # Force gdb to recompute its frames.
200 _gdb_execute("info threads")
201 frame = gdb.newest_frame()
202 assert frame.is_valid()
203 if (frame.older() is not None and
204 frame.older().is_valid() and
205 frame.older().pc() != frame.pc()):
206 frame = frame.older()
207 else:
208 frame = None
209
210 def update_symbols(self, current_thread_only):
194 """Updates the mapping between symbols as seen from GDB and local library 211 """Updates the mapping between symbols as seen from GDB and local library
195 files.""" 212 files.
213
214 If current_thread_only is True, only update symbols for the current thread.
215 """
196 logging.info("Updating symbols") 216 logging.info("Updating symbols")
197 mapped_files = _get_mapped_files() 217 mapped_files = _get_mapped_files()
198 _gdb_execute("info threads")
199 nb_threads = len(_gdb_execute("info threads").split("\n")) - 2
200 # Map all symbols from native libraries packages with the APK. 218 # Map all symbols from native libraries packages with the APK.
201 for file_mappings in mapped_files: 219 for file_mappings in mapped_files:
202 filename = file_mappings[0].filename 220 filename = file_mappings[0].filename
203 if ((filename.startswith('/data/data/') or 221 if ((filename.startswith('/data/data/') or
204 filename.startswith('/data/app')) and 222 filename.startswith('/data/app')) and
205 not filename.endswith('.apk') and 223 not filename.endswith('.apk') and
206 not filename.endswith('.dex')): 224 not filename.endswith('.dex')):
207 logging.info('Pre-mapping: %s' % file_mappings[0].filename) 225 logging.info('Pre-mapping: %s' % file_mappings[0].filename)
ppi 2015/07/23 23:08:31 Why this shift to the right? Not sure which one is
etiennej 2015/07/23 23:21:03 Done.
208 self._try_to_map(file_mappings) 226 self._try_to_map(file_mappings)
209 for i in xrange(nb_threads): 227
210 try: 228 if current_thread_only:
211 _gdb_execute("thread %d" % (i + 1)) 229 self._find_mappings_current_thread(mapped_files)
212 frame = gdb.newest_frame() 230 else:
213 while frame and frame.is_valid(): 231 logging.info('Updating all threads\' symbols')
214 if frame.name() is None: 232 current_thread = gdb.selected_thread()
215 m = self._find_mapping_for_address(mapped_files, frame.pc()) 233 nb_threads = len(_gdb_execute("info threads").split("\n")) - 2
216 if m is not None and self._try_to_map(m): 234 for i in xrange(nb_threads):
217 # Force gdb to recompute its frames. 235 try:
218 _gdb_execute("info threads") 236 _gdb_execute("thread %d" % (i + 1))
219 frame = gdb.newest_frame() 237 self._find_mappings_current_thread(mapped_files)
220 assert frame.is_valid() 238 except gdb.error:
221 if (frame.older() is not None and 239 traceback.print_exc()
222 frame.older().is_valid() and 240 current_thread.switch()
223 frame.older().pc() != frame.pc()):
224 frame = frame.older()
225 else:
226 frame = None
227 except gdb.error:
228 traceback.print_exc()
229 241
230 def _get_device_application_pid(self, application): 242 def _get_device_application_pid(self, application):
231 """Gets the PID of an application running on a device.""" 243 """Gets the PID of an application running on a device."""
232 output = subprocess.check_output([self._adb, 'shell', 'ps']) 244 output = subprocess.check_output([self._adb, 'shell', 'ps'])
233 for line in output.split('\n'): 245 for line in output.split('\n'):
234 elements = line.split() 246 elements = line.split()
235 if len(elements) > 0 and elements[-1] == application: 247 if len(elements) > 0 and elements[-1] == application:
236 return elements[1] 248 return elements[1]
237 return None 249 return None
238 250
(...skipping 20 matching lines...) Expand all
259 remote_file_reader_pid]) 271 remote_file_reader_pid])
260 self._remote_file_reader_process = subprocess.Popen( 272 self._remote_file_reader_process = subprocess.Popen(
261 [self._adb, 'shell', config.REMOTE_FILE_READER_DEVICE_PATH], 273 [self._adb, 'shell', config.REMOTE_FILE_READER_DEVICE_PATH],
262 stdout=subprocess.PIPE, preexec_fn = os.setpgrp) 274 stdout=subprocess.PIPE, preexec_fn = os.setpgrp)
263 port = int(self._remote_file_reader_process.stdout.readline()) 275 port = int(self._remote_file_reader_process.stdout.readline())
264 subprocess.check_call([self._adb, 'forward', 'tcp:10000', 'tcp:%d' % port]) 276 subprocess.check_call([self._adb, 'forward', 'tcp:10000', 'tcp:%d' % port])
265 self._rfc.connect() 277 self._rfc.connect()
266 278
267 _gdb_execute('target remote localhost:9999') 279 _gdb_execute('target remote localhost:9999')
268 280
269 self._update_symbols() 281 self.update_symbols(False)
ppi 2015/07/23 23:08:31 nit: (current_thread_only=True), similarly below
ppi 2015/07/23 23:09:32 I meant (current_thread_only=False).
etiennej 2015/07/23 23:21:03 Done.
270 def on_stop(_): 282 def on_stop(_):
271 self._update_symbols() 283 self.update_symbols(True)
272 gdb.events.stop.connect(on_stop) 284 gdb.events.stop.connect(on_stop)
273 gdb.events.exited.connect(self.stop) 285 gdb.events.exited.connect(self.stop)
286
287 # Register the update-symbols command.
288 UpdateSymbols(self)
289
290 class UpdateSymbols(gdb.Command):
291 """Command to update symbols loaded into GDB.
292
293 GDB usage: update-symbols [all|current]
294 """
295 _UPDATE_COMMAND = "update-symbols"
296
297 def __init__(self, session):
298 super(UpdateSymbols, self).__init__(self._UPDATE_COMMAND, gdb.COMMAND_STACK)
299 self._session = session
300
301 def invoke(self, arg, _unused_from_tty):
302 if arg == 'current':
303 self._session.update_symbols(True)
ppi 2015/07/23 23:08:31 nit: (current_thread_only=True), similarly below
etiennej 2015/07/23 23:21:03 Done.
304 else:
305 self._session.update_symbols(False)
306
307 def complete(self, text, _unused_word):
308 if text == self._UPDATE_COMMAND:
309 return ('all', 'current')
310 elif text in self._UPDATE_COMMAND + ' all':
311 return ['all']
312 elif text in self._UPDATE_COMMAND + ' current':
313 return ['current']
314 else:
315 return []
OLDNEW
« no previous file with comments | « mojo/devtools/common/README.md ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698