macOS: Add LLDB debug script when building with separate debug info (dSYM)
The script will look for the most recent Qt Creator version on the system, and pick up the LLDB summary providers from there, allowing pretty-printing of Qt types inside LLDB/Xcode. LLDB will detect the file when loading the dSYM, and inform the user that the file can be loaded to enable the formatters. The script can be loaded automatically by adding the following setting in ~/.lldbinit: settings set target.load-script-from-symbol-file true Which comes as a slight security risk, as other libraries might have scripts of their own. The alternative is to load the script directly from ~/.lldbinit: command script import "<path to debug script in dSYM>" With an optional target.load-script-from-symbol-file set to false, to silence the warning when loading the dSYM bundle. Change-Id: I01ba51dab725a8d0a58f1ad1749742443b639cc5 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
ddcbe23f20
commit
1b73c202ce
@ -56,6 +56,13 @@ have_target:!static:if(darwin|!isEmpty(QMAKE_OBJCOPY)) {
|
||||
debug_info_plist.input = $$QMAKESPEC/Info.plist.dSYM.in
|
||||
debug_info_plist.output = $${debug_info_target}.$$debug_info_suffix/Contents/Info.plist
|
||||
QMAKE_SUBSTITUTES += debug_info_plist
|
||||
|
||||
!isEmpty(QMAKE_DSYM_DEBUG_SCRIPT) {
|
||||
debug_script.input = $$QMAKE_DSYM_DEBUG_SCRIPT
|
||||
debug_script.output = $${debug_info_target}.$$debug_info_suffix/Contents/Resources/Python/$${TARGET}.py
|
||||
debug_script.CONFIG = verbatim
|
||||
QMAKE_SUBSTITUTES += debug_script
|
||||
}
|
||||
}
|
||||
|
||||
contains(INSTALLS, target):isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) {
|
||||
@ -64,6 +71,11 @@ have_target:!static:if(darwin|!isEmpty(QMAKE_OBJCOPY)) {
|
||||
debug_info_plist_target.files = $${debug_info_target}.$$debug_info_suffix/Contents/Info.plist
|
||||
debug_info_plist_target.path += $${target.path}/$${debug_info_target_rel}.$$debug_info_suffix/Contents
|
||||
INSTALLS += debug_info_plist_target
|
||||
|
||||
debug_script_target.CONFIG += no_check_exist
|
||||
debug_script_target.files = $${debug_info_target}.$$debug_info_suffix/Contents/Resources/Python/$${TARGET}.py
|
||||
debug_script_target.path += $${target.path}/$${debug_info_target_rel}.$$debug_info_suffix/Contents/Resources/Python
|
||||
INSTALLS += debug_script_target
|
||||
}
|
||||
|
||||
debug_info_target.CONFIG += no_check_exist
|
||||
|
@ -146,3 +146,5 @@ ctest_qt5_module_files.files += $$ctest_macros_file.output $$cmake_extras_mkspec
|
||||
ctest_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5Core
|
||||
|
||||
INSTALLS += ctest_qt5_module_files cmake_qt5_umbrella_module_files
|
||||
|
||||
QMAKE_DSYM_DEBUG_SCRIPT = $$PWD/debug_script.py
|
||||
|
98
src/corelib/debug_script.py
Normal file
98
src/corelib/debug_script.py
Normal file
@ -0,0 +1,98 @@
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2017 The Qt Company Ltd.
|
||||
## Contact: https://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the QtCore module of the Qt Toolkit.
|
||||
##
|
||||
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
## Commercial License Usage
|
||||
## Licensees holding valid commercial Qt licenses may use this file in
|
||||
## accordance with the commercial license agreement provided with the
|
||||
## Software or, alternatively, in accordance with the terms contained in
|
||||
## a written agreement between you and The Qt Company. For licensing terms
|
||||
## and conditions see https://www.qt.io/terms-conditions. For further
|
||||
## information use the contact form at https://www.qt.io/contact-us.
|
||||
##
|
||||
## GNU General Public License Usage
|
||||
## Alternatively, this file may be used under the terms of the GNU
|
||||
## General Public License version 3 as published by the Free Software
|
||||
## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
## included in the packaging of this file. Please review the following
|
||||
## information to ensure the GNU General Public License requirements will
|
||||
## be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
##
|
||||
## $QT_END_LICENSE$
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
import os
|
||||
import sys
|
||||
import imp
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
MODULE_NAME = 'qt'
|
||||
|
||||
def import_bridge(path, debugger, session_dict, reload_module = False):
|
||||
if not reload_module and MODULE_NAME in sys.modules:
|
||||
del sys.modules[MODULE_NAME]
|
||||
|
||||
bridge = imp.load_source(MODULE_NAME, path)
|
||||
|
||||
if not hasattr(bridge, '__lldb_init_module'):
|
||||
return None
|
||||
|
||||
# Make available for the current LLDB session, so that LLDB
|
||||
# can find the functions when initializing the module.
|
||||
session_dict[MODULE_NAME] = bridge
|
||||
|
||||
# Initialize the module now that it's available globally
|
||||
bridge.__lldb_init_module(debugger, session_dict)
|
||||
|
||||
if not debugger.GetCategory('Qt'):
|
||||
# Summary provider failed for some reason
|
||||
del session_dict[MODULE_NAME]
|
||||
return None
|
||||
|
||||
return bridge
|
||||
|
||||
def report_success(bridge):
|
||||
print "Using Qt summary providers from Creator %s in '%s'" \
|
||||
% (bridge.CREATOR_VERSION, bridge.CREATOR_PATH)
|
||||
|
||||
def __lldb_init_module(debugger, session_dict):
|
||||
# Check if the module has already been imported globally. This ensures
|
||||
# that the Qt Creator application search is only performed once per
|
||||
# LLDB process invocation, while still reloading for each session.
|
||||
if MODULE_NAME in sys.modules:
|
||||
module = sys.modules[MODULE_NAME]
|
||||
# Reload module for this sessions
|
||||
bridge = import_bridge(module.__file__, debugger, session_dict,
|
||||
reload_module = True)
|
||||
if bridge:
|
||||
report_success(bridge)
|
||||
return
|
||||
|
||||
versions = {}
|
||||
for install in os.popen(
|
||||
'mdfind kMDItemCFBundleIdentifier=org.qt-project.qtcreator'
|
||||
'| while read p;'
|
||||
'do echo $p=$(mdls "$p" -name kMDItemVersion -raw);'
|
||||
'done'):
|
||||
install = install.strip()
|
||||
(p, v) = install.split('=')
|
||||
versions[v] = p
|
||||
|
||||
for version in sorted(versions, key=LooseVersion, reverse=True):
|
||||
path = versions[version]
|
||||
|
||||
bridge_path = path + '/Contents/Resources/debugger/lldbbridge.py'
|
||||
bridge = import_bridge(bridge_path, debugger, session_dict)
|
||||
if bridge:
|
||||
bridge.CREATOR_VERSION = version
|
||||
bridge.CREATOR_PATH = path
|
||||
report_success(bridge)
|
||||
return
|
||||
|
||||
print "Could not find Qt Creator installation, no Qt summary providers installed"
|
Loading…
Reference in New Issue
Block a user