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

Side by Side Diff: mojo/devtools/common/debugger

Issue 1209593002: GDB support for Android in devtools' debugger. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Kill stray remote file reader Created 5 years, 5 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import argparse 6 import argparse
7 import codecs
8 import logging
7 import os.path 9 import os.path
8 import requests 10 import requests
11 import signal
9 import subprocess 12 import subprocess
10 import sys 13 import sys
14 import tempfile
15
16 from android_gdb.install_remote_file_reader import install
11 17
12 _MOJO_DEBUGGER_PORT = 7777 18 _MOJO_DEBUGGER_PORT = 7777
19 _DEFAULT_PACKAGE_NAME = 'org.chromium.mojo.shell'
20
21
22 # TODO(etiennej): Refactor with similar methods in subdirectories
23 class DirectoryNotFoundException(Exception):
24 """Directory has not been found."""
25 pass
26
27 def _get_dir_above(dirname):
28 """Returns the directory "above" this file containing |dirname|."""
29 path = os.path.abspath(__file__)
30 while True:
31 path, tail = os.path.split(path)
32 if not tail:
33 raise DirectoryNotFoundException(dirname)
34 if dirname in os.listdir(path):
35 return path
13 36
14 37
15 def _send_request(request, payload=None): 38 def _send_request(request, payload=None):
16 """Sends a request to mojo:debugger.""" 39 """Sends a request to mojo:debugger."""
17 try: 40 try:
18 url = 'http://localhost:%s/%s' % (_MOJO_DEBUGGER_PORT, request) 41 url = 'http://localhost:%s/%s' % (_MOJO_DEBUGGER_PORT, request)
19 if payload: 42 if payload:
20 return requests.post(url, payload) 43 return requests.post(url, payload)
21 else: 44 else:
22 return requests.get(url) 45 return requests.get(url)
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 stack.wait() 148 stack.wait()
126 149
127 if logcat.returncode: 150 if logcat.returncode:
128 print 'adb logcat failed, make sure the device is connected and available' 151 print 'adb logcat failed, make sure the device is connected and available'
129 return logcat.returncode 152 return logcat.returncode
130 if stack.returncode: 153 if stack.returncode:
131 return stack.returncode 154 return stack.returncode
132 return 0 155 return 0
133 156
134 157
158 def _gdb_attach(args):
159 """Run GDB on an instance of Mojo Shell on an android device."""
160 if args.ndk_dir:
161 ndk_dir = args.ndk_dir
162 else:
163 try:
164 ndk_dir = os.path.join(_get_dir_above('third_party'), 'third_party',
165 'android_tools', 'ndk')
166 if not os.path.exists(ndk_dir):
167 raise DirectoryNotFoundException()
168 except DirectoryNotFoundException:
169 logging.fatal("Unable to find the Android NDK, please specify its path"
170 "with --ndk-dir.")
171 return
172
173 install_args = {}
174 if args.gsutil_dir:
175 install_args['gsutil'] = os.path.join(args.gsutil_dir, 'gsutil')
176 else:
177 try:
178 install_args['gsutil'] = os.path.join(
179 _get_dir_above('depot_tools'), 'depot_tools', 'third_party', 'gsutil',
180 'gsutil')
181 if not os.path.exists(install_args['gsutil']):
182 raise DirectoryNotFoundException()
183 except DirectoryNotFoundException:
184 logging.fatal("Unable to find gsutil, please specify its path"
185 "with --gsutil-dir.")
186 return
187
188 if args.adb_path:
189 install_args['adb'] = args.adb_path
190 install(**install_args)
191
192 gdb_path = os.path.join(
193 ndk_dir,
194 'toolchains',
195 # TODO(etiennej): Always select the most recent toolchain?
196 'arm-linux-androideabi-4.9',
197 'prebuilt',
198 # TODO(etiennej): DEPS mac NDK and use it on macs.
199 'linux-x86_64',
200 'bin',
201 'arm-linux-androideabi-gdb')
202 python_gdb_script_path = os.path.join(os.path.dirname(__file__),
203 'android_gdb', 'session.py')
204 debug_session_arguments = {}
205 if args.build_dir:
206 debug_session_arguments["build_directory"] = args.build_dir
207 else:
208 try:
209 debug_session_arguments["build_directory"] = os.path.join(
210 _get_dir_above('out'), 'out', 'android_Debug')
211 if not os.path.exists(debug_session_arguments["build_directory"]):
212 raise DirectoryNotFoundException()
213 except DirectoryNotFoundException:
214 logging.fatal("Unable to find the build directory, please specify it "
215 "using --build-dir.")
216 return
217
218 if args.package_name:
219 debug_session_arguments["package_name"] = args.package_name
220 else:
221 debug_session_arguments["package_name"] = _DEFAULT_PACKAGE_NAME
222 if args.pyelftools_dir:
223 debug_session_arguments["pyelftools_dir"] = args.pyelftools_dir
224 else:
225 debug_session_arguments["pyelftools_dir"] = os.path.join(
226 _get_dir_above('third_party'), 'third_party', 'pyelftools')
227
228 debug_session_arguments_str = ', '.join(
229 [k + '="' + codecs.encode(v, 'string_escape') + '"'
230 for k, v in debug_session_arguments.items()])
231
232 # We need to pass some commands to GDB at startup.
233 gdb_commands_file = tempfile.NamedTemporaryFile()
234 gdb_commands_file.write('source ' + python_gdb_script_path + '\n')
235 gdb_commands_file.write('py d = DebugSession(' + debug_session_arguments_str
236 + ')\n')
237 gdb_commands_file.write('py d.start()\n')
238 gdb_commands_file.flush()
239
240 gdb_proc = subprocess.Popen([gdb_path, '-x', gdb_commands_file.name],
241 stdin=sys.stdin,
242 stdout=sys.stdout,
243 stderr=sys.stderr)
244
245 # We don't want SIGINT to stop this program. It is automatically propagated by
246 # the system to gdb.
247 signal.signal(signal.SIGINT, signal.SIG_IGN)
248 gdb_proc.wait()
249 signal.signal(signal.SIGINT, signal.SIG_DFL)
250
251
135 def _add_device_command(subparsers): 252 def _add_device_command(subparsers):
136 """Sets up the parser for the 'device' command.""" 253 """Sets up the parser for the 'device' command."""
137 device_parser = subparsers.add_parser('device', 254 device_parser = subparsers.add_parser('device',
138 help='interact with the Android device (requires adb in PATH or passing ' 255 help='interact with the Android device (requires adb in PATH or passing '
139 '--adb-path)') 256 '--adb-path)')
140 device_parser.add_argument('--adb-path', type=str, 257 device_parser.add_argument('--adb-path', type=str,
141 help='path to the adb tool from the Android SDK') 258 help='path to the adb tool from the Android SDK (optional)')
142 device_subparser = device_parser.add_subparsers( 259 device_subparser = device_parser.add_subparsers(
143 help='the command to run') 260 help='the command to run')
144 261
145 device_stack_parser = device_subparser.add_parser('stack', 262 device_stack_parser = device_subparser.add_parser('stack',
146 help='symbolize the crash stacktraces from the device log') 263 help='symbolize the crash stacktraces from the device log')
264 device_stack_parser.add_argument('--ndk-dir', type=str,
265 help='path to the directory containing the Android NDK')
147 device_stack_parser.add_argument('--build-dir', type=str, 266 device_stack_parser.add_argument('--build-dir', type=str,
148 help='path to the build directory') 267 help='path to the build directory')
149 device_stack_parser.add_argument('--ndk-dir', type=str, 268 device_stack_parser.set_defaults(func=_device_stack)
269
270
271 def _add_gdb_command(subparsers):
272 gdb_parser = subparsers.add_parser(
273 'gdb', help='Debug Mojo Shell and its apps using GDB')
274 gdb_subparser = gdb_parser.add_subparsers(
275 help='Commands to GDB')
276
277 gdb_attach_parser = gdb_subparser.add_parser(
278 'attach', help='Attach GDB to a running Mojo Shell process')
279 gdb_attach_parser.add_argument('--adb-path', type=str,
280 help='path to the adb tool from the Android SDK (optional)')
281 gdb_attach_parser.add_argument('--ndk-dir', type=str,
150 help='path to the directory containing the Android NDK') 282 help='path to the directory containing the Android NDK')
151 device_stack_parser.set_defaults(func=_device_stack) 283 gdb_attach_parser.add_argument('--build-dir', type=str,
284 help='path to the build directory')
285 gdb_attach_parser.add_argument('--pyelftools-dir', type=str,
286 help='Path to a directory containing third party libraries')
287 gdb_attach_parser.add_argument('--gsutil-dir', type=str,
288 help='Path to a directory containing gsutil')
289 gdb_attach_parser.add_argument('--package-name', type=str,
290 help='Name of the Mojo Shell android package to debug')
291 gdb_attach_parser.set_defaults(func=_gdb_attach)
152 292
153 293
154 def main(): 294 def main():
155 parser = argparse.ArgumentParser(description='Command-line interface for ' 295 parser = argparse.ArgumentParser(description='Command-line interface for '
156 'mojo:debugger') 296 'mojo:debugger')
157 subparsers = parser.add_subparsers(help='the tool to run') 297 subparsers = parser.add_subparsers(help='the tool to run')
158 _add_device_command(subparsers) 298 _add_device_command(subparsers)
159 _add_tracing_command(subparsers) 299 _add_tracing_command(subparsers)
160 _add_wm_command(subparsers) 300 _add_wm_command(subparsers)
301 _add_gdb_command(subparsers)
161 302
162 args = parser.parse_args() 303 args = parser.parse_args()
163 return args.func(args) 304 return args.func(args)
164 305
165 if __name__ == '__main__': 306 if __name__ == '__main__':
166 sys.exit(main()) 307 sys.exit(main())
OLDNEW
« mojo/devtools/common/android_gdb/session.py ('K') | « mojo/devtools/common/android_gdb/session.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698