blob: e7e226a5681e8c606edd8cff287ce359a9a51aad [file] [log] [blame]
#
# Copyright (C) 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Wraps gdbclient.py to work for out-of-tree builds."""
import os
import shutil
import signal
from cli import clicommand
from commands.product import constants
from core import config
from core import tool
from core import util
class Gdb(clicommand.Command):
"""Run gdbclient.py for a given product."""
remainder_arg = ('args', 'Arguments to pass through to gdbclient.py')
@staticmethod
def Args(parser):
parser.add_argument('-p', '--product_path',
default=util.GetProductDir(),
help='Path to the root of the product')
def LinkToSymbols(self, out_dir, device):
"""Creates a symlink to the symbols directory.
Args:
out_dir: path to the product out/ directory.
device: device name.
"""
built_symbols_path = os.path.join(
out_dir, 'out-' + device, 'target', 'product', device, 'symbols')
gdb_symbols_dir = os.path.join(
out_dir, '.bdk', 'out', 'target', 'product', device)
gdb_symbols_path = os.path.join(gdb_symbols_dir, 'symbols')
if os.path.exists(gdb_symbols_path):
# Blow away whatever might be blocking the symlink we need. This is
# in the .bdk dir so the user shouldn't be keeping anything
# important here.
try:
os.remove(gdb_symbols_path)
except OSError:
# OSError means |gdb_symbols_path| is being blocked by a
# directory.
shutil.rmtree(gdb_symbols_path, ignore_errors=True)
elif not os.path.exists(gdb_symbols_dir):
os.makedirs(gdb_symbols_dir)
os.symlink(built_symbols_path, gdb_symbols_path)
def Run(self, args):
if args.product_path is None:
print constants.MSG_NO_PRODUCT_PATH
return 1
store = config.ProductFileStore(args.product_path)
adb = tool.BrunchHostToolWrapper(store, args.product_path, 'adb')
if not adb.exists():
print 'The product must be built once prior to using gdbclient.py.'
return 1
device = store.device
out_dir = os.path.join(args.product_path, 'out')
try:
self.LinkToSymbols(out_dir, device)
except IOError as e:
print 'Failed to create symlink to built symbols: ' + str(e)
return 1
os_path = util.DEPRECATED_GetDefaultOSPath()
makefile_path = util.GetBDKPath('build', 'wrap-gdb.mk')
make = tool.BrunchToolWrapper(store, args.product_path, 'make')
# Ignore SIGINT, otherwise both this process and the gdb subprocess will
# receive the signal, causing this script to exit instead of just
# pausing gdb as the user intended.
sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
try:
make.run(['make', '-f', makefile_path, 'gdbclient',
'BDK_PATH=' + os_path,
'PRODUCT_BDK=' + os.path.join(out_dir, '.bdk'),
'PRODUCT_NAME=' + store.name,
'BUILDTYPE=' + store.bdk.buildtype,
'ADB_PATH=' + adb.path(),
'GDBCLIENT_ARGS=' + util.AsShellArgs(args.args)])
finally:
signal.signal(signal.SIGINT, sigint_handler)
return 0