Merge remote-tracking branch 'origin/4.2'

Conflicts:
	qbs/modules/qtc/qtc.qbs
	qtcreator.pri
	src/plugins/projectexplorer/kitinformation.cpp

Change-Id: I94299b069418586db97d1d596a252794e4037556
This commit is contained in:
Eike Ziller
2016-12-20 17:14:19 +01:00
61 changed files with 1032 additions and 1621 deletions

82
dist/changes-4.1.1.md vendored
View File

@@ -1,82 +0,0 @@
Qt Creator version 4.1.1 contains bug fixes.
The most important changes are listed in this document. For a complete
list of changes, see the Git log for the Qt Creator sources that
you can check out from the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline v4.1.0..v4.1.1
General
* Fixed issues with output pane height
(QTCREATORBUG-15986, QTCREATORBUG-16829)
Editing
* Fixed performance of cleaning whitespace (QTCREATORBUG-16420)
* Fixed selection color in help viewer for dark theme (QTCREATORBUG-16375)
Help
* Fixed that no results could be shown in Locator (QTCREATORBUG-16753)
QMake Projects
* Fixed issue with make steps in deploy configurations (QTCREATORBUG-16795)
Qbs Projects
* Fixed handling of generated files (QTCREATORBUG-16976)
QML Support
* Fixed handling of circular dependencies (QTCREATORBUG-16585)
Debugging
* Fixed scrolling in memory editor (QTCREATORBUG-16751)
* Fixed expansion of items in tool tip (QTCREATORBUG-16947)
* GDB
* Fixed handling of built-in pretty printers from new versions of GDB
(QTCREATORBUG-16758)
* Fixed that remote working directory was used for local process
(QTCREATORBUG-16211)
* CDB
* Fixed display order of vectors in vectors (QTCREATORBUG-16813)
* Fixed display of QList contents (QTCREATORBUG-16750)
* QML
* Fixed that expansion state was reset when stepping
QML Profiler
* Separated compile events from other QML/JS events in statistics and
flamegraph, since compilation can happen asynchronously
Beautifier
* Fixed that beautifier was not enabled for Objective-C/C++ files
(QTCREATORBUG-16806)
Platform Specific
macOS
* Fixed issue with detecting LLDB through `xcrun`
Android
* Added API level 24 for Android 7
* Fixed debugging on Android 6+ with NDK r11+ (QTCREATORBUG-16721)
iOS
* Fixed simulator support with Xcode 8 (QTCREATORBUG-16942)
Known issue: Qt Creator is blocked until simulator finishes starting
* Fixed that standard paths reported by QStandardPaths were wrong when
running on simulator (QTCREATORBUG-13655)
* Fixed QML debugging on device (QTCREATORBUG-15812)
QNX
* Fixed QML debugging (QTCREATORBUG-17208)

54
dist/changes-4.2.0.md vendored
View File

@@ -17,6 +17,8 @@ General
* Added Help > System Information for bug reporting purposes * Added Help > System Information for bug reporting purposes
(QTCREATORBUG-16135) (QTCREATORBUG-16135)
* Added option to hide the central widget in Debug mode * Added option to hide the central widget in Debug mode
* Fixed issues with output pane height
(QTCREATORBUG-15986, QTCREATORBUG-16829)
Welcome Welcome
@@ -30,10 +32,13 @@ Editing
* Added action for selecting word under cursor (QTCREATORBUG-641) * Added action for selecting word under cursor (QTCREATORBUG-641)
* Fixed highlighting of Markdown files * Fixed highlighting of Markdown files
(QTCREATORBUG-16304) (QTCREATORBUG-16304)
* Fixed performance of cleaning whitespace (QTCREATORBUG-16420)
* Fixed selection color in help viewer for dark theme (QTCREATORBUG-16375)
Help Help
* Added option to open link and current page in window (QTCREATORBUG-16842) * Added option to open link and current page in window (QTCREATORBUG-16842)
* Fixed that no results could be shown in Locator (QTCREATORBUG-16753)
All Projects All Projects
@@ -50,6 +55,7 @@ QMake Projects
(QTCREATORBUG-16558) (QTCREATORBUG-16558)
* Fixed Add Library wizard when selecting library from absolute path or * Fixed Add Library wizard when selecting library from absolute path or
different drive (QTCREATORBUG-8413, QTCREATORBUG-15732, QTCREATORBUG-16688) different drive (QTCREATORBUG-8413, QTCREATORBUG-15732, QTCREATORBUG-16688)
* Fixed issue with make steps in deploy configurations (QTCREATORBUG-16795)
CMake Projects CMake Projects
@@ -64,6 +70,7 @@ CMake Projects
Qbs Projects Qbs Projects
* Made generated files available in project tree (QTCREATORBUG-15978) * Made generated files available in project tree (QTCREATORBUG-15978)
* Fixed handling of generated files (QTCREATORBUG-16976)
C++ Support C++ Support
@@ -78,16 +85,37 @@ C++ Support
* Added notification for parsing errors in headers * Added notification for parsing errors in headers
* Improved responsiveness of completion and highlighting * Improved responsiveness of completion and highlighting
QML Support
* Fixed handling of circular dependencies (QTCREATORBUG-16585)
Debugging Debugging
* Added pretty printing of `QRegExp` captures, `QStaticStringData`, * Added pretty printing of `QRegExp` captures, `QStaticStringData`,
`QStandardItem`, and `std::pair` `QStandardItem`, `std::weak_ptr`, `std::__1::multiset`,
and `std::pair`
* Added display of QObject hierarchy and properties in release builds
* Added support to pretty-print custom types without debug info
* Enhanced display of function pointers
* Improved pretty printing of QV4 types * Improved pretty printing of QV4 types
* Made display of maps more compact * Made display of associative containers, pairs, and various smart
pointers more compact
* Made creation of custom pretty printers easier
* Fixed pretty printing of `QFixed` * Fixed pretty printing of `QFixed`
* Fixed scrolling in memory editor (QTCREATORBUG-16751)
* Fixed expansion of items in tool tip (QTCREATORBUG-16947)
* GDB
* Fixed handling of built-in pretty printers from new versions of GDB
(QTCREATORBUG-16758)
* Fixed that remote working directory was used for local process
(QTCREATORBUG-16211)
* LLDB * LLDB
* Added support for Qt Creator variables `%{...}` in startup commands * Added support for Qt Creator variables `%{...}` in startup commands
* CDB
* Fixed display order of vectors in vectors (QTCREATORBUG-16813)
* Fixed display of QList contents (QTCREATORBUG-16750)
* QML * QML
* Fixed that expansion state was reset when stepping
* Fixed `Load QML Stack` with Qt 5.7 and later (QTCREATORBUG-17097) * Fixed `Load QML Stack` with Qt 5.7 and later (QTCREATORBUG-17097)
QML Profiler QML Profiler
@@ -95,6 +123,8 @@ QML Profiler
* Added option to show memory usage and allocations as flame graph * Added option to show memory usage and allocations as flame graph
* Added option to show vertical orientation lines in timeline * Added option to show vertical orientation lines in timeline
(click the time ruler) (click the time ruler)
* Separated compile events from other QML/JS events in statistics and
flamegraph, since compilation can happen asynchronously
Qt Quick Designer Qt Quick Designer
@@ -142,6 +172,11 @@ Model Editor
* Added zooming * Added zooming
* Added synchronization of selected diagram in diagram browser * Added synchronization of selected diagram in diagram browser
Beautifier
* Fixed that beautifier was not enabled for Objective-C/C++ files
(QTCREATORBUG-16806)
Platform Specific Platform Specific
Windows Windows
@@ -150,9 +185,15 @@ Windows
* Fixed that environment variables containing special characters were not * Fixed that environment variables containing special characters were not
passed correctly to user applications (QTCREATORBUG-17219) passed correctly to user applications (QTCREATORBUG-17219)
macOS
* Fixed issue with detecting LLDB through `xcrun`
Android Android
* Added API level 24 for Android 7
* Improved stability of determination if application is running * Improved stability of determination if application is running
* Fixed debugging on Android 6+ with NDK r11+ (QTCREATORBUG-16721)
* Fixed that running without deployment did not start emulator * Fixed that running without deployment did not start emulator
(QTCREATORBUG-10237) (QTCREATORBUG-10237)
* Fixed that permission model downgrade was not detected as error * Fixed that permission model downgrade was not detected as error
@@ -161,12 +202,19 @@ Android
iOS iOS
* Fixed that Qt Creator was blocked until simulator finished starting * Fixed simulator support with Xcode 8 (QTCREATORBUG-16942)
* Fixed that standard paths reported by QStandardPaths were wrong when
running on simulator (QTCREATORBUG-13655)
* Fixed QML debugging on device (QTCREATORBUG-15812)
Remote Linux Remote Linux
* Fixed crash when creating SSH key pair (QTCREATORBUG-17349) * Fixed crash when creating SSH key pair (QTCREATORBUG-17349)
QNX
* Fixed QML debugging (QTCREATORBUG-17208)
Credits for these changes go to: Credits for these changes go to:
Aaron Barany Aaron Barany
Alessandro Portale Alessandro Portale

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2016 The Qt Company Ltd. Contact: https://www.qt.io/licensing/ --> <!-- Copyright (C) 2016 The Qt Company Ltd. Contact: https://www.qt.io/licensing/ -->
<application> <component type="desktop">
<id type="desktop">qtcreator.desktop</id> <id>org.qt-project.qtcreator.desktop</id>
<licence>CC-BY-SA</licence> <metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<description> <description>
<p> <p>
Qt Creator provides a cross-platform, complete integrated development Qt Creator provides a cross-platform, complete integrated development
@@ -20,9 +21,7 @@
newcomers to Qt. newcomers to Qt.
</p> </p>
</description> </description>
<screenshots>
<screenshot type="default" width="800" height="600">http://qt-project.org/uploads/image_upload/qtcreator-edit-mode.png</screenshot> <url type="homepage">https://qt.io/ide/</url>
</screenshots>
<url type="homepage">https://wiki.qt.io/Category:Tools::QtCreator</url>
<project_group>Qt</project_group> <project_group>Qt</project_group>
</application> </component>

11
dist/org.qt-project.qtcreator.desktop vendored Normal file
View File

@@ -0,0 +1,11 @@
[Desktop Entry]
Type=Application
Exec=qtcreator %F
Name=Qt Creator
GenericName=C++ IDE for developing Qt applications
X-KDE-StartupNotify=true
Icon=QtProject-qtcreator
Terminal=false
Categories=Development;IDE;Qt;
MimeType= text/x-c++src;text/x-c++hdr;text/x-xsrc;application/x-designer;application/vnd.qt.qmakeprofile;application/vnd.qt.xml.resource;

View File

@@ -93,6 +93,16 @@ isEmpty(BASENAME): BASENAME = qt-creator-$${PLATFORM}$(INSTALL_EDITION)-$${QTCRE
macx:INSTALLER_NAME = "qt-creator-$${QTCREATOR_VERSION}" macx:INSTALLER_NAME = "qt-creator-$${QTCREATOR_VERSION}"
else:INSTALLER_NAME = "$${BASENAME}" else:INSTALLER_NAME = "$${BASENAME}"
linux {
appstream.files = dist/org.qt-project.qtcreator.appdata.xml
appstream.path = $$QTC_PREFIX/share/metainfo/
desktop.files = dist/org.qt-project.qtcreator.desktop
desktop.path = $$QTC_PREFIX/share/applications/
INSTALLS += appstream desktop
}
macx { macx {
APPBUNDLE = "$$OUT_PWD/bin/Qt Creator.app" APPBUNDLE = "$$OUT_PWD/bin/Qt Creator.app"
BINDIST_SOURCE = "$$OUT_PWD/bin/Qt Creator.app" BINDIST_SOURCE = "$$OUT_PWD/bin/Qt Creator.app"
@@ -109,7 +119,10 @@ macx {
deployqt.depends = install deployqt.depends = install
win32 { win32 {
deployartifacts.depends = install deployartifacts.depends = install
deployartifacts.commands = git clone "git://code.qt.io/qt-creator/binary-artifacts.git" -b $$BINARY_ARTIFACTS_BRANCH&& xcopy /s /q /y /i "binary-artifacts\\win32" \"$(INSTALL_ROOT)$$QTC_PREFIX\"&& rmdir /s /q binary-artifacts deployartifacts.commands = git clone --depth 1 -b $$BINARY_ARTIFACTS_BRANCH \
"http://code.qt.io/qt-creator/binary-artifacts.git" \
&& xcopy /s /q /y /i "binary-artifacts\\win32" \"$(INSTALL_ROOT)$$QTC_PREFIX\" \
&& rmdir /s /q binary-artifacts
QMAKE_EXTRA_TARGETS += deployartifacts QMAKE_EXTRA_TARGETS += deployartifacts
} }
} }

View File

@@ -24,10 +24,13 @@
############################################################################ ############################################################################
import os import os
import locale
import shutil import shutil
import subprocess import subprocess
import sys import sys
encoding = locale.getdefaultlocale()[1]
def is_windows_platform(): def is_windows_platform():
return sys.platform.startswith('win') return sys.platform.startswith('win')
@@ -88,7 +91,7 @@ def copytree(src, dst, symlinks=False, ignore=None):
def get_qt_install_info(qmake_bin): def get_qt_install_info(qmake_bin):
output = subprocess.check_output([qmake_bin, '-query']) output = subprocess.check_output([qmake_bin, '-query'])
lines = output.strip().split('\n') lines = output.decode(encoding).strip().split('\n')
info = {} info = {}
for line in lines: for line in lines:
(var, sep, value) = line.partition(':') (var, sep, value) = line.partition(':')
@@ -103,7 +106,7 @@ def get_rpath(libfilepath, chrpath=None):
except subprocess.CalledProcessError: # no RPATH or RUNPATH except subprocess.CalledProcessError: # no RPATH or RUNPATH
return [] return []
marker = 'RPATH=' marker = 'RPATH='
index = output.find(marker) index = output.decode(encoding).find(marker)
if index < 0: if index < 0:
marker = 'RUNPATH=' marker = 'RUNPATH='
index = output.find(marker) index = output.find(marker)
@@ -127,7 +130,7 @@ def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None):
# check for Qt linking # check for Qt linking
lddOutput = subprocess.check_output(['ldd', filepath]) lddOutput = subprocess.check_output(['ldd', filepath])
if lddOutput.find('libQt5') >= 0 or lddOutput.find('libicu') >= 0: if lddOutput.decode(encoding).find('libQt5') >= 0 or lddOutput.find('libicu') >= 0:
# add Qt RPATH if necessary # add Qt RPATH if necessary
relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath)) relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath))
if relative_path == '.': if relative_path == '.':

View File

@@ -57,8 +57,9 @@ def parse_arguments():
source_include_patterns = [ source_include_patterns = [
# directories # directories
r"^scripts/.*$", # everything under scripts/ r"^scripts/.*$", # everything under scripts/
r"^src/(.*/)?$", # all directories under src/ r"^src/(.*/)?$", # all directories under src/
r"^plugins/(.*/)?$", # all directories under plugins/ (if this is run on extra plugin repositories)
# files # files
r"^HACKING$", r"^HACKING$",
r"^LICENSE.*$", r"^LICENSE.*$",
@@ -107,12 +108,6 @@ def copy_regexp(regexp, source_directory, target_directory, verbose):
common.copytree(source_directory, target_directory, symlinks=True, ignore=ignore) common.copytree(source_directory, target_directory, symlinks=True, ignore=ignore)
def sanity_check_arguments(arguments): def sanity_check_arguments(arguments):
if not os.path.isfile(os.path.join(arguments.source, 'qtcreator.pri')):
print('error: did not find qtcreator.pri at "{0}"'.format(arguments.source))
return False
if not os.path.isfile(os.path.join(arguments.build, 'src', 'app', 'app_version.h')):
print('error: did not find src/app/app_version.h at "{0}"'.format(arguments.build))
return False
if os.path.exists(arguments.target_directory) and (os.path.isfile(arguments.target_directory) if os.path.exists(arguments.target_directory) and (os.path.isfile(arguments.target_directory)
or len(os.listdir(arguments.target_directory)) > 0): or len(os.listdir(arguments.target_directory)) > 0):
print('error: target directory "{0}" exists and is not empty'.format(arguments.target_directory)) print('error: target directory "{0}" exists and is not empty'.format(arguments.target_directory))

View File

@@ -28,6 +28,7 @@
################################################################################ ################################################################################
import os import os
import locale
import sys import sys
import getopt import getopt
import subprocess import subprocess
@@ -39,9 +40,10 @@ import common
ignoreErrors = False ignoreErrors = False
debug_build = False debug_build = False
encoding = locale.getdefaultlocale()[1]
def usage(): def usage():
print "Usage: %s <creator_install_dir> [qmake_path]" % os.path.basename(sys.argv[0]) print("Usage: %s <creator_install_dir> [qmake_path]" % os.path.basename(sys.argv[0]))
def which(program): def which(program):
def is_exe(fpath): def is_exe(fpath):
@@ -73,14 +75,14 @@ def is_debug(fpath):
if coredebug.search(fpath): if coredebug.search(fpath):
return True return True
output = subprocess.check_output(['dumpbin', '/imports', fpath]) output = subprocess.check_output(['dumpbin', '/imports', fpath])
return coredebug.search(output) != None return coredebug.search(output.decode(encoding)) != None
def is_debug_build(install_dir): def is_debug_build(install_dir):
return is_debug(os.path.join(install_dir, 'bin', 'qtcreator.exe')) return is_debug(os.path.join(install_dir, 'bin', 'qtcreator.exe'))
def op_failed(details = None): def op_failed(details = None):
if details != None: if details != None:
print details print(details)
if ignoreErrors == False: if ignoreErrors == False:
print("Error: operation failed!") print("Error: operation failed!")
sys.exit(2) sys.exit(2)
@@ -108,7 +110,7 @@ def ignored_qt_lib_files(path, filenames):
return [fn for fn in filenames if is_ignored_windows_file(debug_build, path, fn)] return [fn for fn in filenames if is_ignored_windows_file(debug_build, path, fn)]
def copy_qt_libs(target_qt_prefix_path, qt_bin_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_dir, plugins, imports): def copy_qt_libs(target_qt_prefix_path, qt_bin_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_dir, plugins, imports):
print "copying Qt libraries..." print("copying Qt libraries...")
if common.is_windows_platform(): if common.is_windows_platform():
libraries = glob(os.path.join(qt_libs_dir, '*.dll')) libraries = glob(os.path.join(qt_libs_dir, '*.dll'))
@@ -127,7 +129,7 @@ def copy_qt_libs(target_qt_prefix_path, qt_bin_dir, qt_libs_dir, qt_plugin_dir,
libraries = [lib for lib in libraries if not is_ignored_windows_file(debug_build, '', lib)] libraries = [lib for lib in libraries if not is_ignored_windows_file(debug_build, '', lib)]
for library in libraries: for library in libraries:
print library, '->', lib_dest print(library, '->', lib_dest)
if os.path.islink(library): if os.path.islink(library):
linkto = os.readlink(library) linkto = os.readlink(library)
try: try:
@@ -137,7 +139,7 @@ def copy_qt_libs(target_qt_prefix_path, qt_bin_dir, qt_libs_dir, qt_plugin_dir,
else: else:
shutil.copy(library, lib_dest) shutil.copy(library, lib_dest)
print "Copying plugins:", plugins print("Copying plugins:", plugins)
for plugin in plugins: for plugin in plugins:
target = os.path.join(target_qt_prefix_path, 'plugins', plugin) target = os.path.join(target_qt_prefix_path, 'plugins', plugin)
if (os.path.exists(target)): if (os.path.exists(target)):
@@ -147,7 +149,7 @@ def copy_qt_libs(target_qt_prefix_path, qt_bin_dir, qt_libs_dir, qt_plugin_dir,
print('{0} -> {1}'.format(pluginPath, target)) print('{0} -> {1}'.format(pluginPath, target))
common.copytree(pluginPath, target, ignore=ignored_qt_lib_files, symlinks=True) common.copytree(pluginPath, target, ignore=ignored_qt_lib_files, symlinks=True)
print "Copying imports:", imports print("Copying imports:", imports)
for qtimport in imports: for qtimport in imports:
target = os.path.join(target_qt_prefix_path, 'imports', qtimport) target = os.path.join(target_qt_prefix_path, 'imports', qtimport)
if (os.path.exists(target)): if (os.path.exists(target)):
@@ -158,14 +160,14 @@ def copy_qt_libs(target_qt_prefix_path, qt_bin_dir, qt_libs_dir, qt_plugin_dir,
common.copytree(import_path, target, ignore=ignored_qt_lib_files, symlinks=True) common.copytree(import_path, target, ignore=ignored_qt_lib_files, symlinks=True)
if (os.path.exists(qt_qml_dir)): if (os.path.exists(qt_qml_dir)):
print "Copying qt quick 2 imports" print("Copying qt quick 2 imports")
target = os.path.join(target_qt_prefix_path, 'qml') target = os.path.join(target_qt_prefix_path, 'qml')
if (os.path.exists(target)): if (os.path.exists(target)):
shutil.rmtree(target) shutil.rmtree(target)
print('{0} -> {1}'.format(qt_qml_dir, target)) print('{0} -> {1}'.format(qt_qml_dir, target))
common.copytree(qt_qml_dir, target, ignore=ignored_qt_lib_files, symlinks=True) common.copytree(qt_qml_dir, target, ignore=ignored_qt_lib_files, symlinks=True)
print "Copying qtdiag" print("Copying qtdiag")
bin_dest = target_qt_prefix_path if common.is_windows_platform() else os.path.join(target_qt_prefix_path, 'bin') bin_dest = target_qt_prefix_path if common.is_windows_platform() else os.path.join(target_qt_prefix_path, 'bin')
qtdiag_src = os.path.join(qt_bin_dir, 'qtdiag.exe' if common.is_windows_platform() else 'qtdiag') qtdiag_src = os.path.join(qt_bin_dir, 'qtdiag.exe' if common.is_windows_platform() else 'qtdiag')
if not os.path.exists(bin_dest): if not os.path.exists(bin_dest):
@@ -191,9 +193,9 @@ def copy_translations(install_dir, qt_tr_dir):
translations = glob(os.path.join(qt_tr_dir, '*.qm')) translations = glob(os.path.join(qt_tr_dir, '*.qm'))
tr_dir = os.path.join(install_dir, 'share', 'qtcreator', 'translations') tr_dir = os.path.join(install_dir, 'share', 'qtcreator', 'translations')
print "copying translations..." print("copying translations...")
for translation in translations: for translation in translations:
print translation, '->', tr_dir print(translation, '->', tr_dir)
shutil.copy(translation, tr_dir) shutil.copy(translation, tr_dir)
def copyPreservingLinks(source, destination): def copyPreservingLinks(source, destination):
@@ -240,21 +242,21 @@ def deploy_libclang(install_dir, llvm_install_dir, chrpath_bin):
os.path.join(clangbinary_targetdir, linktarget))) os.path.join(clangbinary_targetdir, linktarget)))
resourcetarget = os.path.join(install_dir, 'libexec', 'qtcreator', 'clang', 'lib', 'clang') resourcetarget = os.path.join(install_dir, 'libexec', 'qtcreator', 'clang', 'lib', 'clang')
print "copying libclang..." print("copying libclang...")
for source, target in deployinfo: for source, target in deployinfo:
print source, '->', target print(source, '->', target)
copyPreservingLinks(source, target) copyPreservingLinks(source, target)
if common.is_linux_platform(): if common.is_linux_platform():
# libclang was statically compiled, so there is no need for the RPATHs # libclang was statically compiled, so there is no need for the RPATHs
# and they are confusing when fixing RPATHs later in the process # and they are confusing when fixing RPATHs later in the process
print "removing libclang RPATHs..." print("removing libclang RPATHs...")
for source, target in deployinfo: for source, target in deployinfo:
if not os.path.islink(target): if not os.path.islink(target):
targetfilepath = target if not os.path.isdir(target) else os.path.join(target, os.path.basename(source)) targetfilepath = target if not os.path.isdir(target) else os.path.join(target, os.path.basename(source))
subprocess.check_call([chrpath_bin, '-d', targetfilepath]) subprocess.check_call([chrpath_bin, '-d', targetfilepath])
print resourcesource, '->', resourcetarget print(resourcesource, '->', resourcetarget)
if (os.path.exists(resourcetarget)): if (os.path.exists(resourcetarget)):
shutil.rmtree(resourcetarget) shutil.rmtree(resourcetarget)
common.copytree(resourcesource, resourcetarget, symlinks=True) common.copytree(resourcesource, resourcetarget, symlinks=True)
@@ -272,7 +274,7 @@ def main():
if o in ('-i', '--ignore-errors'): if o in ('-i', '--ignore-errors'):
global ignoreErrors global ignoreErrors
ignoreErrors = True ignoreErrors = True
print "Note: Ignoring all errors" print("Note: Ignoring all errors")
if len(args) < 1: if len(args) < 1:
usage() usage()
@@ -289,14 +291,14 @@ def main():
qmake_bin = which(qmake_bin) qmake_bin = which(qmake_bin)
if qmake_bin == None: if qmake_bin == None:
print "Cannot find required binary 'qmake'." print("Cannot find required binary 'qmake'.")
sys.exit(2) sys.exit(2)
chrpath_bin = None chrpath_bin = None
if common.is_linux_platform(): if common.is_linux_platform():
chrpath_bin = which('chrpath') chrpath_bin = which('chrpath')
if chrpath_bin == None: if chrpath_bin == None:
print "Cannot find required binary 'chrpath'." print("Cannot find required binary 'chrpath'.")
sys.exit(2) sys.exit(2)
qt_install_info = common.get_qt_install_info(qmake_bin) qt_install_info = common.get_qt_install_info(qmake_bin)
@@ -323,7 +325,7 @@ def main():
deploy_libclang(install_dir, os.environ["LLVM_INSTALL_DIR"], chrpath_bin) deploy_libclang(install_dir, os.environ["LLVM_INSTALL_DIR"], chrpath_bin)
if not common.is_windows_platform(): if not common.is_windows_platform():
print "fixing rpaths..." print("fixing rpaths...")
common.fix_rpaths(install_dir, os.path.join(qt_deploy_prefix, 'lib'), qt_install_info, chrpath_bin) common.fix_rpaths(install_dir, os.path.join(qt_deploy_prefix, 'lib'), qt_install_info, chrpath_bin)
add_qt_conf(os.path.join(install_dir, 'libexec', 'qtcreator'), qt_deploy_prefix) # e.g. for qml2puppet add_qt_conf(os.path.join(install_dir, 'libexec', 'qtcreator'), qt_deploy_prefix) # e.g. for qml2puppet
add_qt_conf(os.path.join(qt_deploy_prefix, 'bin'), qt_deploy_prefix) # e.g. qtdiag add_qt_conf(os.path.join(qt_deploy_prefix, 'bin'), qt_deploy_prefix) # e.g. qtdiag
@@ -331,7 +333,7 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
if common.is_mac_platform(): if common.is_mac_platform():
print "Mac OS is not supported by this script, please use macqtdeploy!" print("macOS is not supported by this script, please use macqtdeploy!")
sys.exit(2) sys.exit(2)
else: else:
main() main()

122
scripts/msanalyzer2tasks.pl Executable file
View File

@@ -0,0 +1,122 @@
#!/usr/bin/perl -w
############################################################################
#
# Copyright (C) 2016 The Qt Company Ltd.
# Contact: https://www.qt.io/licensing/
#
# This file is part of Qt Creator.
#
# 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.
#
############################################################################
=head1 NAME
msanalyzer2tasks.pl - Convert MSVC/Static analyzer warnings and errors into Qt Creator task files.
=head1 SYNOPSIS
msanalyzer2tasks.pl < logfile > taskfile
=cut
# Sample:
# <DEFECTS>
# <DEFECT>
# <SFA>
# <FILEPATH>c:\dev\qt5\qtbase\src\corelib\statemachine\</FILEPATH>
# <FILENAME>qstatemachine.cpp</FILENAME>
# <LINE>968</LINE>
# <COLUMN>21</COLUMN>
# </SFA>
# <DEFECTCODE>6246</DEFECTCODE>
# <DESCRIPTION>Local declaration of 'i' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '953' of 'c:\dev\qt5\qtbase\src\corelib\statemachine\qstatemachine.cpp'.</DESCRIPTION>
# <FUNCTION>QStateMachinePrivate::enterStates</FUNCTION>
# <DECORATED>?enterStates@QStateMachinePrivate@@UAEXPAVQEvent@@ABV?$QList@PAVQAbstractState@@@@1ABV?$QSet@PAVQAbstractState@@@@AAV?$QHash@PAVQAbstractState@@V?$QVector@UQPropertyAssignment@@@@@@ABV?$QList@PAVQAbstractAnimation@@@@@Z</DECORATED>
# <FUNCLINE>941</FUNCLINE>
# <PATH>
# <SFA>
# <FILEPATH>c:\dev\qt5\qtbase\src\corelib\statemachine\</FILEPATH>
# <FILENAME>qstatemachine.cpp</FILENAME>
# <LINE>953</LINE>
# <COLUMN>18</COLUMN>
# </SFA>
# </PATH>
# </DEFECT>
# <DEFECT>
use strict;
my ($description, $defectCode);
my (@filePaths, @fileNames, @lineNumbers);
# Return element contents of a line "<ELEMENT>Contents</ELEMENT>"
sub elementContents
{
my ($line) = @_;
return $line =~ /^ *<([^>]*)>([^<]*)<\/.*$/
? ($1, $2) : (undef, undef)
}
# Fix path 'c:\foo\' -> 'c:/foo'
sub fixFilePath
{
my ($p) = @_;
$p =~ s|\\|/|g;
my $lastSlash = rindex($p, '/');
chop($p) if $lastSlash == length($p) - 1;
return $p;
}
# Fix message (replace XML entities, backslash)
sub fixMessage
{
my ($m) = @_;
$m =~ s|\\|/|g;
$m =~ s/&lt;/</g;
$m =~ s/&gt;/>/g;
$m =~ s/&amp;/&/g;
return $m;
}
while (my $line = <STDIN> ) {
chomp($line);
my ($element, $content) = elementContents($line);
if (defined($element)) {
if ($element eq 'FILEPATH') {
push(@filePaths, fixFilePath($content));
} elsif ($element eq 'FILENAME') {
push(@fileNames, $content);
} elsif ($element eq 'LINE') {
push(@lineNumbers, $content);
} elsif ($element eq 'DESCRIPTION') {
$description = fixMessage($content);
} elsif ($element eq 'DEFECTCODE') {
$defectCode = $content;
}
} elsif (index($line, '</DEFECT>') >= 0) {
my $count = scalar(@filePaths);
for (my $i = 0; $i < $count; $i++) {
my $text = $description;
$text .= ' (' . $defectCode . ')' if defined $defectCode;
print $filePaths[$i], '/', $fileNames[$i], "\t", $lineNumbers[$i], "\twarn\t", $text,"\n";
}
$description = $defectCode = undef;
@filePaths = @fileNames= @lineNumbers = ();
}
}

View File

@@ -472,6 +472,9 @@ class DumperBase:
self.cachedFormats[typeName] = stripped self.cachedFormats[typeName] = stripped
return stripped return stripped
def templateArgument(self, typeobj, position):
return typeobj.templateArgument(position)
def intType(self): def intType(self):
result = self.lookupType('int') result = self.lookupType('int')
self.intType = lambda: result self.intType = lambda: result
@@ -1858,7 +1861,7 @@ class DumperBase:
for i in range(propertyCount): for i in range(propertyCount):
t = self.split('III', dataPtr + properties * 4 + 12 * i) t = self.split('III', dataPtr + properties * 4 + 12 * i)
name = self.metaString(metaObjectPtr, t[0], revision) name = self.metaString(metaObjectPtr, t[0], revision)
if qobject: if qobject and self.qtPropertyFunc:
# LLDB doesn't like calling it on a derived class, possibly # LLDB doesn't like calling it on a derived class, possibly
# due to type information living in a different shared object. # due to type information living in a different shared object.
#base = self.createValue(qobjectPtr, '@QObject') #base = self.createValue(qobjectPtr, '@QObject')
@@ -1875,6 +1878,10 @@ class DumperBase:
continue continue
#warn('COULD NOT EXECUTE: %s' % cmd) #warn('COULD NOT EXECUTE: %s' % cmd)
#self.putCallItem(name, '@QVariant', base, 'property', '"' + name + '"') #self.putCallItem(name, '@QVariant', base, 'property', '"' + name + '"')
if res is None:
self.bump('failedMetaObjectCall2')
putt(name, ' ')
continue
self.putSubItem(name, res) self.putSubItem(name, res)
else: else:
putt(name, ' ') putt(name, ' ')
@@ -2876,9 +2883,12 @@ class DumperBase:
elif isinstance(index, self.dumper.Field): elif isinstance(index, self.dumper.Field):
field = index field = index
elif self.dumper.isInt(index): elif self.dumper.isInt(index):
if self.type.code in (TypeCodeArray, TypeCodePointer): if self.type.code == TypeCodeArray:
itemAddress = self.laddress + int(index) * self.type.ltarget.size() addr = self.laddress + int(index) * self.type.ltarget.size()
return self.dumper.createValue(itemAddress, self.type.ltarget) return self.dumper.createValue(addr, self.type.ltarget)
if self.type.code == TypeCodePointer:
addr = self.pointer() + int(index) * self.type.ltarget.size()
return self.dumper.createValue(addr, self.type.ltarget)
return self.members(False)[index] return self.members(False)[index]
else: else:
error('BAD INDEX TYPE %s' % type(index)) error('BAD INDEX TYPE %s' % type(index))

View File

@@ -1049,7 +1049,7 @@ class Dumper(DumperBase):
sym += '@plt' sym += '@plt'
self.qtCustomEventPltFunc = self.findSymbol(sym) self.qtCustomEventPltFunc = self.findSymbol(sym)
sym = '_ZNK7%sQObject8propertyEPKc' % strns sym = '_ZNK%s7QObject8propertyEPKc' % strns
self.qtPropertyFunc = self.findSymbol(sym) self.qtPropertyFunc = self.findSymbol(sym)
# This might be wrong, but we can't do better: We found # This might be wrong, but we can't do better: We found

View File

@@ -341,3 +341,11 @@ def qdump__WTF__String(d, value):
def qdump__QtcDumperTest_FieldAccessByIndex(d, value): def qdump__QtcDumperTest_FieldAccessByIndex(d, value):
d.putValue(value["d"][2].integer()) d.putValue(value["d"][2].integer())
def qdump__QtcDumperTest_PointerArray(d, value):
foos = value["foos"]
d.putItemCount(10)
if d.isExpanded():
with Children(d, 10):
for i in d.childRange():
d.putSubItem(i, foos[i])

View File

@@ -296,6 +296,7 @@ void TimelineItemsGeometry::allocate(QSGMaterial *material)
{ {
QSGGeometry *geometry = new QSGGeometry(OpaqueColoredPoint2DWithSize::attributes(), QSGGeometry *geometry = new QSGGeometry(OpaqueColoredPoint2DWithSize::attributes(),
usedVertices); usedVertices);
Q_ASSERT(geometry->vertexData());
geometry->setIndexDataPattern(QSGGeometry::StaticPattern); geometry->setIndexDataPattern(QSGGeometry::StaticPattern);
geometry->setVertexDataPattern(QSGGeometry::StaticPattern); geometry->setVertexDataPattern(QSGGeometry::StaticPattern);
node = new QSGGeometryNode; node = new QSGGeometryNode;

View File

@@ -196,6 +196,7 @@ QSGGeometry *NotesGeometry::createGeometry(QVector<int> &ids, const TimelineMode
float rowHeight = TimelineModel::defaultRowHeight(); float rowHeight = TimelineModel::defaultRowHeight();
QSGGeometry *geometry = new QSGGeometry(point2DWithDistanceFromTop(), QSGGeometry *geometry = new QSGGeometry(point2DWithDistanceFromTop(),
ids.count() * 2); ids.count() * 2);
Q_ASSERT(geometry->vertexData());
geometry->setDrawingMode(GL_LINES); geometry->setDrawingMode(GL_LINES);
geometry->setLineWidth(3); geometry->setLineWidth(3);
Point2DWithDistanceFromTop *v = Point2DWithDistanceFromTop *v =

View File

@@ -36,6 +36,7 @@ QSGGeometryNode *createSelectionNode(QSGMaterial *material)
selectionNode->setMaterial(material); selectionNode->setMaterial(material);
selectionNode->setFlag(QSGNode::OwnsMaterial, false); selectionNode->setFlag(QSGNode::OwnsMaterial, false);
QSGGeometry *geometry = new QSGGeometry(OpaqueColoredPoint2DWithSize::attributes(), 4); QSGGeometry *geometry = new QSGGeometry(OpaqueColoredPoint2DWithSize::attributes(), 4);
Q_ASSERT(geometry->vertexData());
geometry->setDrawingMode(GL_TRIANGLE_STRIP); geometry->setDrawingMode(GL_TRIANGLE_STRIP);
OpaqueColoredPoint2DWithSize *v = OpaqueColoredPoint2DWithSize::fromVertexData(geometry); OpaqueColoredPoint2DWithSize *v = OpaqueColoredPoint2DWithSize::fromVertexData(geometry);
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)

View File

@@ -544,6 +544,8 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
void TestResultsPane::onCopyItemTriggered(const QModelIndex &idx) void TestResultsPane::onCopyItemTriggered(const QModelIndex &idx)
{ {
if (!idx.isValid())
return;
const TestResult *result = m_filterModel->testResult(idx); const TestResult *result = m_filterModel->testResult(idx);
QTC_ASSERT(result, return); QTC_ASSERT(result, return);
QApplication::clipboard()->setText(result->outputString(true)); QApplication::clipboard()->setText(result->outputString(true));

View File

@@ -1488,6 +1488,9 @@ void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigati
if (d->m_currentEditor == editor) if (d->m_currentEditor == editor)
return; return;
emit m_instance->currentEditorAboutToChange(d->m_currentEditor);
if (d->m_currentEditor && !ignoreNavigationHistory) if (d->m_currentEditor && !ignoreNavigationHistory)
EditorManager::addCurrentPositionToNavigationHistory(); EditorManager::addCurrentPositionToNavigationHistory();

View File

@@ -189,6 +189,7 @@ signals:
void findOnFileSystemRequest(const QString &path); void findOnFileSystemRequest(const QString &path);
void aboutToSave(IDocument *document); void aboutToSave(IDocument *document);
void autoSaved(); void autoSaved();
void currentEditorAboutToChange(Core::IEditor *editor);
public slots: public slots:
static void saveDocument(); static void saveDocument();

View File

@@ -34,7 +34,7 @@ namespace AsynchronousMessageBox {
namespace { namespace {
void message(QMessageBox::Icon icon, const QString &title, const QString &desciption) QWidget *message(QMessageBox::Icon icon, const QString &title, const QString &desciption)
{ {
QMessageBox *messageBox = new QMessageBox(icon, QMessageBox *messageBox = new QMessageBox(icon,
title, title,
@@ -45,23 +45,24 @@ void message(QMessageBox::Icon icon, const QString &title, const QString &descip
messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->setAttribute(Qt::WA_DeleteOnClose);
messageBox->setModal(true); messageBox->setModal(true);
messageBox->show(); messageBox->show();
return messageBox;
} }
} }
void warning(const QString &title, const QString &desciption) QWidget *warning(const QString &title, const QString &desciption)
{ {
message(QMessageBox::Warning, title, desciption); return message(QMessageBox::Warning, title, desciption);
} }
void information(const QString &title, const QString &desciption) QWidget *information(const QString &title, const QString &desciption)
{ {
message(QMessageBox::Information, title, desciption); return message(QMessageBox::Information, title, desciption);
} }
void critical(const QString &title, const QString &desciption) QWidget *critical(const QString &title, const QString &desciption)
{ {
message(QMessageBox::Critical, title, desciption); return message(QMessageBox::Critical, title, desciption);
}
} }
} }
}

View File

@@ -29,13 +29,15 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QString; class QString;
class QWidget;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Core { namespace Core {
namespace AsynchronousMessageBox { namespace AsynchronousMessageBox {
CORE_EXPORT void warning(const QString &title, const QString &desciption); CORE_EXPORT QWidget *warning(const QString &title, const QString &desciption);
CORE_EXPORT void information(const QString &title, const QString &desciption); CORE_EXPORT QWidget *information(const QString &title, const QString &desciption);
CORE_EXPORT void critical(const QString &title, const QString &desciption); CORE_EXPORT QWidget *critical(const QString &title, const QString &desciption);
} }
} }

View File

@@ -383,6 +383,7 @@ public:
// Safety net to avoid infinite lookups. // Safety net to avoid infinite lookups.
QSet<QString> m_lookupRequests; // FIXME: Integrate properly. QSet<QString> m_lookupRequests; // FIXME: Integrate properly.
QPointer<QWidget> m_alertBox;
}; };
@@ -1825,8 +1826,11 @@ QString DebuggerEngine::msgInterrupted()
return tr("Interrupted."); return tr("Interrupted.");
} }
void DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name) bool DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name)
{ {
if (d->m_alertBox)
return false;
if (name.isEmpty()) if (name.isEmpty())
name = ' ' + tr("<Unknown>", "name") + ' '; name = ' ' + tr("<Unknown>", "name") + ' ';
if (meaning.isEmpty()) if (meaning.isEmpty())
@@ -1836,7 +1840,9 @@ void DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name
"<table><tr><td>Signal name : </td><td>%1</td></tr>" "<table><tr><td>Signal name : </td><td>%1</td></tr>"
"<tr><td>Signal meaning : </td><td>%2</td></tr></table>") "<tr><td>Signal meaning : </td><td>%2</td></tr></table>")
.arg(name, meaning); .arg(name, meaning);
AsynchronousMessageBox::information(tr("Signal Received"), msg);
d->m_alertBox = AsynchronousMessageBox::information(tr("Signal Received"), msg);
return true;
} }
void DebuggerEngine::showStoppedByExceptionMessageBox(const QString &description) void DebuggerEngine::showStoppedByExceptionMessageBox(const QString &description)

View File

@@ -430,7 +430,7 @@ protected:
static QString msgStoppedByException(const QString &description, static QString msgStoppedByException(const QString &description,
const QString &threadId); const QString &threadId);
static QString msgInterrupted(); static QString msgInterrupted();
void showStoppedBySignalMessageBox(const QString meaning, QString name); bool showStoppedBySignalMessageBox(const QString meaning, QString name);
void showStoppedByExceptionMessageBox(const QString &description); void showStoppedByExceptionMessageBox(const QString &description);
bool isStateDebugging() const; bool isStateDebugging() const;

View File

@@ -1634,7 +1634,10 @@ void GdbEngine::handleStop2(const GdbMi &data)
} else { } else {
showMessage("HANDLING SIGNAL " + name); showMessage("HANDLING SIGNAL " + name);
if (boolSetting(UseMessageBoxForSignals) && !isStopperThread) if (boolSetting(UseMessageBoxForSignals) && !isStopperThread)
showStoppedBySignalMessageBox(meaning, name); if (!showStoppedBySignalMessageBox(meaning, name)) {
showMessage("SIGNAL RECEIVED WHILE SHOWING SIGNAL MESSAGE");
return;
}
if (!name.isEmpty() && !meaning.isEmpty()) if (!name.isEmpty() && !meaning.isEmpty())
reasontr = msgStoppedBySignal(meaning, name); reasontr = msgStoppedBySignal(meaning, name);
} }

View File

@@ -8680,6 +8680,11 @@ void FakeVimHandler::handleInput(const QString &keys)
d->leaveFakeVim(); d->leaveFakeVim();
} }
void FakeVimHandler::enterCommandMode()
{
d->enterCommandMode();
}
void FakeVimHandler::setCurrentFileName(const QString &fileName) void FakeVimHandler::setCurrentFileName(const QString &fileName)
{ {
d->m_currentFileName = fileName; d->m_currentFileName = fileName;

View File

@@ -106,6 +106,7 @@ public:
void handleCommand(const QString &cmd); void handleCommand(const QString &cmd);
void handleReplay(const QString &keys); void handleReplay(const QString &keys);
void handleInput(const QString &keys); void handleInput(const QString &keys);
void enterCommandMode();
void installEventFilter(); void installEventFilter();

View File

@@ -1035,6 +1035,7 @@ private:
void onCoreAboutToClose(); void onCoreAboutToClose();
void editorOpened(Core::IEditor *); void editorOpened(Core::IEditor *);
void editorAboutToClose(Core::IEditor *); void editorAboutToClose(Core::IEditor *);
void currentEditorAboutToChange(Core::IEditor *);
void allDocumentsRenamed(const QString &oldName, const QString &newName); void allDocumentsRenamed(const QString &oldName, const QString &newName);
void documentRenamed(Core::IDocument *document, const QString &oldName, const QString &newName); void documentRenamed(Core::IDocument *document, const QString &oldName, const QString &newName);
@@ -1246,6 +1247,8 @@ bool FakeVimPluginPrivate::initialize()
this, &FakeVimPluginPrivate::editorAboutToClose); this, &FakeVimPluginPrivate::editorAboutToClose);
connect(EditorManager::instance(), &EditorManager::editorOpened, connect(EditorManager::instance(), &EditorManager::editorOpened,
this, &FakeVimPluginPrivate::editorOpened); this, &FakeVimPluginPrivate::editorOpened);
connect(EditorManager::instance(), &EditorManager::currentEditorAboutToChange,
this, &FakeVimPluginPrivate::currentEditorAboutToChange);
connect(DocumentManager::instance(), &DocumentManager::allDocumentsRenamed, connect(DocumentManager::instance(), &DocumentManager::allDocumentsRenamed,
this, &FakeVimPluginPrivate::allDocumentsRenamed); this, &FakeVimPluginPrivate::allDocumentsRenamed);
@@ -1841,6 +1844,12 @@ void FakeVimPluginPrivate::editorAboutToClose(IEditor *editor)
m_editorToHandler.remove(editor); m_editorToHandler.remove(editor);
} }
void FakeVimPluginPrivate::currentEditorAboutToChange(IEditor *editor)
{
if (FakeVimHandler *handler = m_editorToHandler.value(editor, 0))
handler->enterCommandMode();
}
void FakeVimPluginPrivate::allDocumentsRenamed(const QString &oldName, const QString &newName) void FakeVimPluginPrivate::allDocumentsRenamed(const QString &oldName, const QString &newName)
{ {
renameFileNameInEditors(oldName, newName); renameFileNameInEditors(oldName, newName);

View File

@@ -169,8 +169,6 @@ IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
m_runner, &IosRunner::start); m_runner, &IosRunner::start);
connect(m_runControl, &RunControl::finished, connect(m_runControl, &RunControl::finished,
m_runner, &IosRunner::stop); m_runner, &IosRunner::stop);
connect(m_runControl, &DebuggerRunControl::stateChanged,
m_runner, &IosRunner::debuggerStateChanged);
connect(m_runner, &IosRunner::gotServerPorts, connect(m_runner, &IosRunner::gotServerPorts,
this, &IosDebugSupport::handleServerPorts); this, &IosDebugSupport::handleServerPorts);

View File

@@ -168,12 +168,6 @@ void IosRunner::stop()
} }
} }
void IosRunner::debuggerStateChanged(Debugger::DebuggerState state)
{
if (m_toolHandler)
m_toolHandler->debuggerStateChanged(state);
}
void IosRunner::handleDidStartApp(IosToolHandler *handler, const QString &bundlePath, void IosRunner::handleDidStartApp(IosToolHandler *handler, const QString &bundlePath,
const QString &deviceId, IosToolHandler::OpStatus status) const QString &deviceId, IosToolHandler::OpStatus status)
{ {

View File

@@ -65,9 +65,6 @@ public:
void start(); void start();
void stop(); void stop();
public slots:
void debuggerStateChanged(Debugger::DebuggerState state);
signals: signals:
void didStartApp(Ios::IosToolHandler::OpStatus status); void didStartApp(Ios::IosToolHandler::OpStatus status);
void gotServerPorts(Utils::Port gdbPort, Utils::Port qmlPort); void gotServerPorts(Utils::Port gdbPort, Utils::Port qmlPort);

View File

@@ -34,6 +34,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include "utils/runextensions.h" #include "utils/runextensions.h"
#include "utils/synchronousprocess.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QFileInfo> #include <QFileInfo>
@@ -141,7 +142,6 @@ public:
bool isRunning(); bool isRunning();
void start(const QString &exe, const QStringList &args); void start(const QString &exe, const QStringList &args);
virtual void stop(int errorCode) = 0; virtual void stop(int errorCode) = 0;
virtual void debuggerStateChanged(Debugger::DebuggerState state) { Q_UNUSED(state); }
// signals // signals
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress, void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
@@ -230,20 +230,10 @@ private:
* YES | * YES |
* | | * | |
* v | * v |
* +---------+-------------------------+ | * +---------+------------------------------+ |
* | SimulatorControl::spawnAppProcess | <------------------+ * | SimulatorControl::launchAppOnSimulator | <-------------+
* +-----------------------------------+ * +----------------------------------------+
* | *
* v
* +--------+-----------+ +-----------------------------+
* | Debug Run ? +---YES------> + Wait for debugger to attach |
* +---------+----------+ +-----------+-----------------+
* NO |
* | |
* v |
* +-----------------------------+ |
* | SimulatorControl::launchApp | <-------------------+
* +-----------------------------+
***************************************************************************/ ***************************************************************************/
class IosSimulatorToolHandlerPrivate : public IosToolHandlerPrivate class IosSimulatorToolHandlerPrivate : public IosToolHandlerPrivate
{ {
@@ -260,15 +250,11 @@ public:
const QString &deviceIdentifier, int timeout = 1000) override; const QString &deviceIdentifier, int timeout = 1000) override;
void requestDeviceInfo(const QString &deviceId, int timeout = 1000) override; void requestDeviceInfo(const QString &deviceId, int timeout = 1000) override;
void stop(int errorCode) override; void stop(int errorCode) override;
void debuggerStateChanged(Debugger::DebuggerState state) override;
private: private:
void installAppOnSimulator(); void installAppOnSimulator();
void spawnAppOnSimulator(const QStringList &extraArgs); void launchAppOnSimulator(const QStringList &extraArgs);
void launchAppOnSimulator();
bool isResponseValid(const SimulatorControl::ResponseData &responseData); bool isResponseValid(const SimulatorControl::ResponseData &responseData);
void onResponseAppSpawn(const SimulatorControl::ResponseData &response);
void simAppProcessError(QProcess::ProcessError error); void simAppProcessError(QProcess::ProcessError error);
void simAppProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); void simAppProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
@@ -277,7 +263,6 @@ private:
private: private:
qint64 appPId = -1; qint64 appPId = -1;
bool appLaunched = false;
SimulatorControl *simCtl; SimulatorControl *simCtl;
QList<QFuture<void>> futureList; QList<QFuture<void>> futureList;
}; };
@@ -802,7 +787,7 @@ void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
if (isResponseValid(response)) if (isResponseValid(response))
return; return;
if (response.success) { if (response.success) {
spawnAppOnSimulator(extraArgs); launchAppOnSimulator(extraArgs);
} else { } else {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. Simulator not running.") errorMsg(IosToolHandler::tr("Application launch on Simulator failed. Simulator not running.")
.arg(bundlePath)); .arg(bundlePath));
@@ -811,7 +796,7 @@ void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
}; };
if (SimulatorControl::isSimulatorRunning(deviceId)) if (SimulatorControl::isSimulatorRunning(deviceId))
spawnAppOnSimulator(extraArgs); launchAppOnSimulator(extraArgs);
else else
futureList << Utils::onResultReady(simCtl->startSimulator(deviceId), onSimulatorStart); futureList << Utils::onResultReady(simCtl->startSimulator(deviceId), onSimulatorStart);
} }
@@ -824,14 +809,7 @@ void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId,
void IosSimulatorToolHandlerPrivate::stop(int errorCode) void IosSimulatorToolHandlerPrivate::stop(int errorCode)
{ {
appPId = -1;
if (process) {
QTC_ASSERT(process.unique(), process->kill(); qCDebug(toolHandlerLog)<<"App process is not unique.");
process.reset();
appPId = -1;
appLaunched = false;
}
foreach (auto f, futureList) { foreach (auto f, futureList) {
if (!f.isFinished()) if (!f.isFinished())
f.cancel(); f.cancel();
@@ -841,14 +819,6 @@ void IosSimulatorToolHandlerPrivate::stop(int errorCode)
q->finished(q); q->finished(q);
} }
void IosSimulatorToolHandlerPrivate::debuggerStateChanged(Debugger::DebuggerState state)
{
if (!appLaunched && state == Debugger::DebuggerState::InferiorRunOk) {
// Debugger attached. Launch it on the simulator.
launchAppOnSimulator();
}
}
void IosSimulatorToolHandlerPrivate::installAppOnSimulator() void IosSimulatorToolHandlerPrivate::installAppOnSimulator()
{ {
auto onResponseAppInstall = [this](const SimulatorControl::ResponseData &response) { auto onResponseAppInstall = [this](const SimulatorControl::ResponseData &response) {
@@ -871,23 +841,32 @@ void IosSimulatorToolHandlerPrivate::installAppOnSimulator()
onResponseAppInstall); onResponseAppInstall);
} }
void IosSimulatorToolHandlerPrivate::spawnAppOnSimulator(const QStringList &extraArgs) void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &extraArgs)
{ {
Utils::FileName appBundle = Utils::FileName::fromString(bundlePath); auto monitorPid = [this](QFutureInterface<int> &fi, qint64 pid) {
bool debugRun = runKind == IosToolHandler::DebugRun; int exitCode = 0;
futureList << Utils::onResultReady(simCtl->spawnAppProcess(deviceId, appBundle, debugRun, extraArgs), const QStringList args({QStringLiteral("-0"), QString::number(pid)});
std::bind(&IosSimulatorToolHandlerPrivate::onResponseAppSpawn, this, _1)); Utils::SynchronousProcess pKill;
} while (!fi.isCanceled() && exitCode == 0) {
// Poll every 1 sec to check whether the app is running.
QThread::msleep(1000);
Utils::SynchronousProcessResponse resp = pKill.runBlocking(QStringLiteral("kill"), args);
exitCode = resp.exitCode;
}
// Future is cancelled if the app is stopped from the qt creator.
if (!fi.isCanceled())
stop(0);
};
void IosSimulatorToolHandlerPrivate::launchAppOnSimulator() auto onResponseAppLaunch = [this, monitorPid](const SimulatorControl::ResponseData &response) {
{
auto onResponseAppLaunch = [this](const SimulatorControl::ResponseData &response) {
if (!isResponseValid(response)) if (!isResponseValid(response))
return; return;
if (response.success) {
if (response.pID != -1) { appPId = response.pID;
appLaunched = true; gotInferiorPid(bundlePath, deviceId, appPId);
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Success); didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Success);
// Start monitoring app's life signs.
futureList << Utils::runAsync(monitorPid, appPId);
} else { } else {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. %1") errorMsg(IosToolHandler::tr("Application launch on Simulator failed. %1")
.arg(QString::fromLocal8Bit(response.commandOutput))); .arg(QString::fromLocal8Bit(response.commandOutput)));
@@ -896,16 +875,11 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator()
q->finished(q); q->finished(q);
} }
}; };
Utils::FileName appBundle = Utils::FileName::fromString(bundlePath);
if (appPId != -1) { futureList << Utils::onResultReady(simCtl->launchApp(deviceId,
Utils::FileName appBundle = Utils::FileName::fromString(bundlePath); SimulatorControl::bundleIdentifier(appBundle),
futureList << Utils::onResultReady(simCtl->launchApp(deviceId, runKind == IosToolHandler::DebugRun,
SimulatorControl::bundleIdentifier(appBundle), appPId), extraArgs), onResponseAppLaunch);
onResponseAppLaunch);
} else {
errorMsg(IosToolHandler::tr("Spawning the Application process on Simulator failed. Spawning timed out."));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
}
} }
bool IosSimulatorToolHandlerPrivate::isResponseValid(const SimulatorControl::ResponseData &responseData) bool IosSimulatorToolHandlerPrivate::isResponseValid(const SimulatorControl::ResponseData &responseData)
@@ -921,40 +895,6 @@ bool IosSimulatorToolHandlerPrivate::isResponseValid(const SimulatorControl::Res
return true; return true;
} }
void IosSimulatorToolHandlerPrivate::onResponseAppSpawn(const SimulatorControl::ResponseData &response)
{
if (!isResponseValid(response))
return;
if (response.processInstance) {
QTC_ASSERT(!process || !isRunning(),
qCDebug(toolHandlerLog) << "Spwaning app while an app instance exits.");
process = response.processInstance;
QObject::connect(process.get(), &QProcess::readyReadStandardOutput,
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessHasData, this));
QObject::connect(process.get(), &QProcess::readyReadStandardError,
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessHasErrorOutput, this));
QObject::connect(process.get(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessFinished, this, _1, _2));
QObject::connect(process.get(), &QProcess::errorOccurred,
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessError, this, _1));
appPId = response.pID;
gotInferiorPid(bundlePath, deviceId, appPId);
// For normal run. Launch app on Simulator.
// For debug run, wait for the debugger to attach and then launch the app.
if (runKind == IosToolHandler::NormalRun)
launchAppOnSimulator();
} else {
errorMsg(IosToolHandler::tr("Spawning the Application process on Simulator failed. %1")
.arg(QString::fromLocal8Bit(response.commandOutput)));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
stop(-1);
q->finished(q);
}
}
void IosSimulatorToolHandlerPrivate::simAppProcessError(QProcess::ProcessError error) void IosSimulatorToolHandlerPrivate::simAppProcessError(QProcess::ProcessError error)
{ {
errorMsg(IosToolHandler::tr("Simulator application process error %1").arg(error)); errorMsg(IosToolHandler::tr("Simulator application process error %1").arg(error));
@@ -1010,11 +950,6 @@ void IosToolHandler::stop()
d->stop(-1); d->stop(-1);
} }
void IosToolHandler::debuggerStateChanged(int state)
{
d->debuggerStateChanged((Debugger::DebuggerState)state);
}
void IosToolHandler::requestTransferApp(const QString &bundlePath, const QString &deviceId, void IosToolHandler::requestTransferApp(const QString &bundlePath, const QString &deviceId,
int timeout) int timeout)
{ {

View File

@@ -64,7 +64,6 @@ public:
void requestDeviceInfo(const QString &deviceId, int timeout = 1000); void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
bool isRunning(); bool isRunning();
void stop(); void stop();
void debuggerStateChanged(int state);
signals: signals:
void isTransferringApp(Ios::IosToolHandler *handler, const QString &bundlePath, void isTransferringApp(Ios::IosToolHandler *handler, const QString &bundlePath,

View File

@@ -42,13 +42,7 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMap>
#include <QProcess> #include <QProcess>
#include <QReadLocker>
#include <QReadWriteLock>
#include <QTime>
#include <QUrl>
#include <QWriteLocker>
using namespace std; using namespace std;
@@ -63,7 +57,7 @@ static int COMMAND_TIMEOUT = 10000;
static int SIMULATOR_START_TIMEOUT = 60000; static int SIMULATOR_START_TIMEOUT = 60000;
static QString SIM_UDID_TAG = QStringLiteral("SimUdid"); static QString SIM_UDID_TAG = QStringLiteral("SimUdid");
static bool checkForTimeout(const chrono::time_point< chrono::high_resolution_clock, chrono::nanoseconds> &start, int msecs = COMMAND_TIMEOUT) static bool checkForTimeout(const chrono::high_resolution_clock::time_point &start, int msecs = COMMAND_TIMEOUT)
{ {
bool timedOut = false; bool timedOut = false;
auto end = chrono::high_resolution_clock::now(); auto end = chrono::high_resolution_clock::now();
@@ -75,6 +69,7 @@ static bool checkForTimeout(const chrono::time_point< chrono::high_resolution_cl
static bool runCommand(QString command, const QStringList &args, QByteArray *output) static bool runCommand(QString command, const QStringList &args, QByteArray *output)
{ {
Utils::SynchronousProcess p; Utils::SynchronousProcess p;
p.setTimeoutS(-1);
Utils::SynchronousProcessResponse resp = p.runBlocking(command, args); Utils::SynchronousProcessResponse resp = p.runBlocking(command, args);
if (output) if (output)
*output = resp.allRawOutput(); *output = resp.allRawOutput();
@@ -89,31 +84,6 @@ static QByteArray runSimCtlCommand(QStringList args)
return output; return output;
} }
static bool waitForProcessSpawn(qint64 processPId, QFutureInterface<SimulatorControl::ResponseData> &fi)
{
bool success = false;
if (processPId != -1) {
// Wait for app to reach intruptible sleep state.
const QStringList args = {QStringLiteral("-p"), QString::number(processPId),
QStringLiteral("-o"), QStringLiteral("wq=")};
int wqCount = -1;
QByteArray wqStr;
auto begin = chrono::high_resolution_clock::now();
do {
if (fi.isCanceled() || !runCommand(QStringLiteral("ps"), args, &wqStr))
break;
bool validInt = false;
wqCount = wqStr.trimmed().toInt(&validInt);
if (!validInt)
wqCount = -1;
} while (wqCount < 0 && !checkForTimeout(begin));
success = wqCount >= 0;
} else {
qCDebug(simulatorLog) << "Wait for spawned failed. Invalid Process ID." << processPId;
}
return success;
}
class SimulatorControlPrivate { class SimulatorControlPrivate {
private: private:
struct SimDeviceInfo { struct SimDeviceInfo {
@@ -136,11 +106,9 @@ private:
void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid); void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid);
void installApp(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid, void installApp(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid,
const Utils::FileName &bundlePath); const Utils::FileName &bundlePath);
void spawnAppProcess(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid,
const Utils::FileName &bundlePath, bool waitForDebugger, QStringList extraArgs,
QThread *mainThread);
void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid, void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid,
const QString &bundleIdentifier, qint64 spawnedPID); const QString &bundleIdentifier, bool waitForDebugger,
const QStringList &extraArgs);
static QList<IosDeviceType> availableDevices; static QList<IosDeviceType> availableDevices;
friend class SimulatorControl; friend class SimulatorControl;
@@ -215,7 +183,7 @@ QString SimulatorControl::bundleExecutable(const Utils::FileName &bundlePath)
return SimulatorControlPrivate::bundleExecutable(bundlePath); return SimulatorControlPrivate::bundleExecutable(bundlePath);
} }
QFuture<SimulatorControl::ResponseData> SimulatorControl::startSimulator(const QString &simUdid) QFuture<SimulatorControl::ResponseData> SimulatorControl::startSimulator(const QString &simUdid) const
{ {
return Utils::runAsync(&SimulatorControlPrivate::startSimulator, d, simUdid); return Utils::runAsync(&SimulatorControlPrivate::startSimulator, d, simUdid);
} }
@@ -226,20 +194,12 @@ SimulatorControl::installApp(const QString &simUdid, const Utils::FileName &bund
return Utils::runAsync(&SimulatorControlPrivate::installApp, d, simUdid, bundlePath); return Utils::runAsync(&SimulatorControlPrivate::installApp, d, simUdid, bundlePath);
} }
QFuture<SimulatorControl::ResponseData>
SimulatorControl::spawnAppProcess(const QString &simUdid, const Utils::FileName &bundlePath,
bool waitForDebugger, const QStringList &extraArgs) const
{
return Utils::runAsync(&SimulatorControlPrivate::spawnAppProcess, d, simUdid, bundlePath,
waitForDebugger, extraArgs, QThread::currentThread());
}
QFuture<SimulatorControl::ResponseData> QFuture<SimulatorControl::ResponseData>
SimulatorControl::launchApp(const QString &simUdid, const QString &bundleIdentifier, SimulatorControl::launchApp(const QString &simUdid, const QString &bundleIdentifier,
qint64 spawnedPID) const bool waitForDebugger, const QStringList &extraArgs) const
{ {
return Utils::runAsync(&SimulatorControlPrivate::launchApp, d, simUdid, return Utils::runAsync(&SimulatorControlPrivate::launchApp, d, simUdid, bundleIdentifier,
bundleIdentifier, spawnedPID); waitForDebugger, extraArgs);
} }
QList<IosDeviceType> SimulatorControlPrivate::availableDevices; QList<IosDeviceType> SimulatorControlPrivate::availableDevices;
@@ -362,7 +322,6 @@ void SimulatorControlPrivate::startSimulator(QFutureInterface<SimulatorControl::
} }
if (!fi.isCanceled()) { if (!fi.isCanceled()) {
QThread::msleep(500); // give it some time. TODO: find an actual fix.
fi.reportResult(response); fi.reportResult(response);
} }
} }
@@ -377,118 +336,31 @@ void SimulatorControlPrivate::installApp(QFutureInterface<SimulatorControl::Resp
response.commandOutput = output; response.commandOutput = output;
if (!fi.isCanceled()) { if (!fi.isCanceled()) {
QThread::msleep(500); // give it some time. TODO: find an actual fix.
fi.reportResult(response);
}
}
void SimulatorControlPrivate::spawnAppProcess(QFutureInterface<SimulatorControl::ResponseData> &fi,
const QString &simUdid, const Utils::FileName &bundlePath,
bool waitForDebugger, QStringList extraArgs, QThread *mainThread)
{
SimulatorControl::ResponseData response(simUdid);
// Find the path of the installed app.
QString bundleId = bundleIdentifier(bundlePath);
QByteArray appContainer = runSimCtlCommand({QStringLiteral("get_app_container"), simUdid, bundleId});
QString appPath = QString::fromLocal8Bit(appContainer.trimmed());
if (fi.isCanceled())
return;
QString executableName = bundleExecutable(bundlePath);
if (!appPath.isEmpty() && !executableName.isEmpty()) {
appPath.append('/' + executableName);
QStringList args = {QStringLiteral("simctl"), QStringLiteral("spawn"), simUdid, appPath};
if (waitForDebugger)
args.insert(2, QStringLiteral("-w"));
args << extraArgs;
// Spawn the app. The spawned app is started in suspended mode.
shared_ptr<QProcess> simCtlProcess(new QProcess, [](QProcess *p) {
if (p->state() != QProcess::NotRunning) {
p->kill();
p->waitForFinished(COMMAND_TIMEOUT);
}
delete p;
});
simCtlProcess->start(QStringLiteral("xcrun"), args);
if (simCtlProcess->waitForStarted()) {
if (fi.isCanceled())
return;
// Find the process id of the spawned app.
qint64 simctlPId = simCtlProcess->processId();
QByteArray commandOutput;
const QStringList pGrepArgs = {QStringLiteral("-f"), appPath};
auto begin = chrono::high_resolution_clock::now();
int processID = -1;
while (processID == -1 && runCommand(QStringLiteral("pgrep"), pGrepArgs, &commandOutput)) {
if (fi.isCanceled()) {
qCDebug(simulatorLog) <<"Spawning the app failed. Future cancelled.";
return;
}
foreach (auto pidStr, commandOutput.trimmed().split('\n')) {
qint64 parsedPId = pidStr.toLongLong();
if (parsedPId != simctlPId)
processID = parsedPId;
}
if (checkForTimeout(begin)) {
qCDebug(simulatorLog) << "Spawning the app failed. Process timed out";
break;
}
}
if (processID == -1) {
qCDebug(simulatorLog) << "Spawning the app failed. App PID not found.";
simCtlProcess->waitForReadyRead(COMMAND_TIMEOUT);
response.commandOutput = simCtlProcess->readAllStandardError();
} else {
response.processInstance = simCtlProcess;
response.processInstance->moveToThread(mainThread);
response.pID = processID;
response.success = true;
}
} else {
qCDebug(simulatorLog) << "Spawning the app failed." << simCtlProcess->errorString();
response.commandOutput = simCtlProcess->errorString().toLatin1();
}
} else {
qCDebug(simulatorLog) << "Spawning the app failed. Check installed app." << appPath;
}
if (!fi.isCanceled()) {
QThread::msleep(500); // give it some time. TODO: find an actual fix.
fi.reportResult(response); fi.reportResult(response);
} }
} }
void SimulatorControlPrivate::launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, void SimulatorControlPrivate::launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi,
const QString &simUdid, const QString &bundleIdentifier, const QString &simUdid, const QString &bundleIdentifier,
qint64 spawnedPID) bool waitForDebugger, const QStringList &extraArgs)
{ {
SimulatorControl::ResponseData response(simUdid); SimulatorControl::ResponseData response(simUdid);
if (!bundleIdentifier.isEmpty()) { if (!bundleIdentifier.isEmpty() && !fi.isCanceled()) {
bool processSpawned = true; QStringList args({QStringLiteral("launch"), simUdid, bundleIdentifier});
// Wait for the process to be spawned properly before launching app.
if (spawnedPID > -1)
processSpawned = waitForProcessSpawn(spawnedPID, fi);
if (fi.isCanceled()) if (waitForDebugger)
return; args.insert(1, QStringLiteral("-w"));
if (processSpawned) { foreach (const QString extraArgument, extraArgs) {
QThread::msleep(500); // give it some time. TODO: find an actual fix. if (!extraArgument.trimmed().isEmpty())
const QStringList args({QStringLiteral("launch"), simUdid , bundleIdentifier}); args << extraArgument;
response.commandOutput = runSimCtlCommand(args);
const QByteArray pIdStr = response.commandOutput.trimmed().split(' ').last().trimmed();
bool validInt = false;
response.pID = pIdStr.toLongLong(&validInt);
if (!validInt) {
// Launch Failed.
qCDebug(simulatorLog) << "Launch app failed. Process id returned is not valid. PID =" << pIdStr;
response.pID = -1;
}
} }
response.commandOutput = runSimCtlCommand(args);
const QByteArray pIdStr = response.commandOutput.trimmed().split(' ').last().trimmed();
bool validPid = false;
response.pID = pIdStr.toLongLong(&validPid);
response.success = validPid;
} }
if (!fi.isCanceled()) { if (!fi.isCanceled()) {

View File

@@ -52,9 +52,6 @@ public:
bool success = false; bool success = false;
qint64 pID = -1; qint64 pID = -1;
QByteArray commandOutput = ""; QByteArray commandOutput = "";
// For response type APP_SPAWN, the processInstance represents the control process of the spwaned app
// For other response types its null.
std::shared_ptr<QProcess> processInstance;
}; };
public: public:
@@ -69,12 +66,10 @@ public:
static QString bundleExecutable(const Utils::FileName &bundlePath); static QString bundleExecutable(const Utils::FileName &bundlePath);
public: public:
QFuture<ResponseData> startSimulator(const QString &simUdid); QFuture<ResponseData> startSimulator(const QString &simUdid) const;
QFuture<ResponseData> installApp(const QString &simUdid, const Utils::FileName &bundlePath) const; QFuture<ResponseData> installApp(const QString &simUdid, const Utils::FileName &bundlePath) const;
QFuture<ResponseData> spawnAppProcess(const QString &simUdid, const Utils::FileName &bundlePath,
bool waitForDebugger, const QStringList &extraArgs) const;
QFuture<ResponseData> launchApp(const QString &simUdid, const QString &bundleIdentifier, QFuture<ResponseData> launchApp(const QString &simUdid, const QString &bundleIdentifier,
qint64 spawnedPID = -1) const; bool waitForDebugger, const QStringList &extraArgs) const;
private: private:
SimulatorControlPrivate *d; SimulatorControlPrivate *d;

View File

@@ -164,7 +164,9 @@ static QList<Abi> parseCoffHeader(const QByteArray &data)
flavor = Abi::WindowsMsvc2013Flavor; flavor = Abi::WindowsMsvc2013Flavor;
break; break;
case 14: case 14:
flavor = Abi::WindowsMsvc2015Flavor; flavor = minorLinker >= quint8(10)
? Abi::WindowsMsvc2017Flavor // MSVC2017 RC
: Abi::WindowsMsvc2015Flavor;
break; break;
case 15: case 15:
flavor = Abi::WindowsMsvc2017Flavor; flavor = Abi::WindowsMsvc2017Flavor;

View File

@@ -291,6 +291,15 @@ void Kit::setup()
info.at(i)->setup(this); info.at(i)->setup(this);
} }
void Kit::upgrade()
{
KitGuard g(this);
// Process the KitInfos in reverse order: They may only be based on other information lower in
// the stack.
for (KitInformation *ki : KitManager::kitInformation())
ki->upgrade(this);
}
QString Kit::unexpandedDisplayName() const QString Kit::unexpandedDisplayName() const
{ {
return d->m_unexpandedDisplayName; return d->m_unexpandedDisplayName;

View File

@@ -69,6 +69,7 @@ public:
void fix(); // Fix the individual kit information: Make sure it contains a valid value. void fix(); // Fix the individual kit information: Make sure it contains a valid value.
// Fix will not look at other information in the kit! // Fix will not look at other information in the kit!
void setup(); // Apply advanced magic(TM). Used only once on each kit during initial setup. void setup(); // Apply advanced magic(TM). Used only once on each kit during initial setup.
void upgrade(); // Upgrade settings to new syntax (if appropriate).
QString unexpandedDisplayName() const; QString unexpandedDisplayName() const;
QString displayName() const; QString displayName() const;

View File

@@ -197,7 +197,9 @@ QList<Task> ToolChainKitInformation::validate(const Kit *k) const
void ToolChainKitInformation::upgrade(Kit *k) void ToolChainKitInformation::upgrade(Kit *k)
{ {
// upgrade <=4.1 to 4.2 (keep old settings around for now) // upgrade <=4.1 to 4.2 (keep old settings around for now)
const QVariant oldValue = k->value("PE.Profile.ToolChain"); const Core::Id oldId = "PE.Profile.ToolChain";
const QVariant oldValue = k->value(oldId);
const QVariant value = k->value(ToolChainKitInformation::id()); const QVariant value = k->value(ToolChainKitInformation::id());
if (value.isNull() && !oldValue.isNull()) { if (value.isNull() && !oldValue.isNull()) {
QVariantMap newValue; QVariantMap newValue;
@@ -216,6 +218,7 @@ void ToolChainKitInformation::upgrade(Kit *k)
} }
} }
k->setValue(ToolChainKitInformation::id(), newValue); k->setValue(ToolChainKitInformation::id(), newValue);
k->setSticky(ToolChainKitInformation::id(), k->isSticky(oldId));
} }
} }
@@ -224,8 +227,9 @@ void ToolChainKitInformation::fix(Kit *k)
QTC_ASSERT(ToolChainManager::isLoaded(), return); QTC_ASSERT(ToolChainManager::isLoaded(), return);
foreach (ToolChain::Language l, ToolChain::allLanguages()) { foreach (ToolChain::Language l, ToolChain::allLanguages()) {
if (!toolChain(k, l)) { if (!toolChain(k, l)) {
qWarning("No tool chain set from kit \"%s\".", qWarning("No tool chain set up in kit \"%s\" for \"%s\".",
qPrintable(k->displayName())); qPrintable(k->displayName()),
qPrintable(ToolChain::languageDisplayName(l)));
clearToolChain(k, l); // make sure to clear out no longer known tool chains clearToolChain(k, l); // make sure to clear out no longer known tool chains
} }
} }

View File

@@ -165,6 +165,7 @@ void KitManager::restoreKits()
Kit *toStore = 0; Kit *toStore = 0;
foreach (Kit *current, kitsToValidate) { foreach (Kit *current, kitsToValidate) {
toStore = current; toStore = current;
toStore->upgrade();
toStore->setup(); // Make sure all kitinformation are properly set up before merging them toStore->setup(); // Make sure all kitinformation are properly set up before merging them
// with the information from the user settings file // with the information from the user settings file

View File

@@ -218,9 +218,7 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
data.insert(QLatin1String(QBS_ARCHITECTURE), qbs::canonicalArchitecture(architecture)); data.insert(QLatin1String(QBS_ARCHITECTURE), qbs::canonicalArchitecture(architecture));
} }
QStringList targetOS = targetOSList(targetAbi, k); data.insert(QLatin1String(QBS_TARGETOS), targetOSList(targetAbi, k));
if (!targetOS.isEmpty())
data.insert(QLatin1String(QBS_TARGETOS), targetOS);
QStringList toolchain = toolchainList(mainTc); QStringList toolchain = toolchainList(mainTc);

View File

@@ -72,16 +72,21 @@ void QmakeKitInformation::setup(Kit *k)
if (!version) if (!version)
return; return;
if (version->type() == "Boot2Qt.QtVersionType") // HACK: Ignore boot2Qt kits!
return;
FileName spec = QmakeKitInformation::mkspec(k); FileName spec = QmakeKitInformation::mkspec(k);
if (spec.isEmpty()) if (spec.isEmpty())
spec = version->mkspec(); spec = version->mkspec();
ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx); ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
if (!tc || (!tc->suggestedMkspecList().empty() && !tc->suggestedMkspecList().contains(spec))) { if (!tc || (!tc->suggestedMkspecList().empty() && !tc->suggestedMkspecList().contains(spec))) {
ToolChain *possibleTc = 0; ToolChain *possibleTc = nullptr;
foreach (ToolChain *current, ToolChainManager::toolChains()) { foreach (ToolChain *current, ToolChainManager::toolChains()) {
if (version->qtAbis().contains(current->targetAbi())) { if (current->language() == ToolChain::Language::Cxx
&& version->qtAbis().contains(current->targetAbi())) {
possibleTc = current; possibleTc = current;
if (current->suggestedMkspecList().contains(spec)) if (current->suggestedMkspecList().contains(spec))
break; break;

View File

@@ -231,6 +231,7 @@ void BindlingLoopsGeometry::allocate(QSGMaterial *material)
{ {
QSGGeometry *geometry = new QSGGeometry(BindlingLoopsGeometry::point2DWithOffset(), QSGGeometry *geometry = new QSGGeometry(BindlingLoopsGeometry::point2DWithOffset(),
usedVertices); usedVertices);
Q_ASSERT(geometry->vertexData());
geometry->setIndexDataPattern(QSGGeometry::StaticPattern); geometry->setIndexDataPattern(QSGGeometry::StaticPattern);
geometry->setVertexDataPattern(QSGGeometry::StaticPattern); geometry->setVertexDataPattern(QSGGeometry::StaticPattern);
node = new QSGGeometryNode; node = new QSGGeometryNode;

View File

@@ -44,7 +44,8 @@ namespace TextEditor {
Keywords::Keywords(const QStringList &variables, const QStringList &functions, const QMap<QString, QStringList> &functionArgs) Keywords::Keywords(const QStringList &variables, const QStringList &functions, const QMap<QString, QStringList> &functionArgs)
: m_variables(variables), m_functions(functions), m_functionArgs(functionArgs) : m_variables(variables), m_functions(functions), m_functionArgs(functionArgs)
{ {
Utils::sort(m_variables);
Utils::sort(m_functions);
} }
bool Keywords::isVariable(const QString &word) const bool Keywords::isVariable(const QString &word) const

View File

@@ -0,0 +1,370 @@
<?xml version="1.0"?>
<valgrindoutput>
<protocolversion>4</protocolversion>
<protocoltool>memcheck</protocoltool>
<preamble>
<line>Memcheck, a memory error detector</line>
<line>Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.</line>
<line>Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info</line>
<line>Command: kate</line>
</preamble>
<pid>22733</pid>
<ppid>17584</ppid>
<tool>memcheck</tool>
<args>
<vargv>
<exe>/usr/bin/valgrind.bin</exe>
<arg>--suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp</arg>
<arg>--xml=yes</arg>
<arg>--xml-file=test.xml</arg>
<arg>--track-origins=yes</arg>
</vargv>
<argv>
<exe>kate</exe>
</argv>
</args>
<status>
<state>RUNNING</state>
<time>00:00:00:00.241 </time>
</status>
<error>
<unique>0x9</unique>
<tid>1</tid>
<kind>InvalidRead</kind>
<what>Invalid read of size 4</what>
<stack>
<frame>
<ip>0x6E47964</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QFrame::frameStyle() const</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/widgets</dir>
<file>qframe.cpp</file>
<line>252</line>
</frame>
<frame>
<ip>0x118F2AF7</ip>
<obj>/usr/lib/kde4/plugins/styles/oxygen.so</obj>
</frame>
<frame>
<ip>0x6A81671</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QWidget::event(QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qwidget.cpp</file>
<line>8273</line>
</frame>
<frame>
<ip>0x6A2B6EB</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QApplicationPrivate::notify_helper(QObject*, QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qapplication.cpp</file>
<line>4396</line>
</frame>
<!--
<frame>
<ip>0x6A311DC</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QApplication::notify(QObject*, QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qapplication.cpp</file>
<line>4277</line>
</frame>
<frame>
<ip>0x6443535</ip>
<obj>/usr/lib/libkdeui.so.5.5.0</obj>
<fn>KApplication::notify(QObject*, QEvent*)</fn>
</frame>
<frame>
<ip>0x83690AB</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QCoreApplication::notifyInternal(QObject*, QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/kernel</dir>
<file>qcoreapplication.cpp</file>
<line>732</line>
</frame>
<frame>
<ip>0x6A77600</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QWidget::ensurePolished() const</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/../../include/QtCore/../../src/corelib/kernel</dir>
<file>qcoreapplication.h</file>
<line>215</line>
</frame>
<frame>
<ip>0x6A869B2</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QWidget::setVisible(bool)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qwidget.cpp</file>
<line>7539</line>
</frame>
<frame>
<ip>0x18B1ED35</ip>
<obj>/home/milian/projects/compiled/kde4/lib/libkatepartinterfaces.so.4.5.0</obj>
<fn>QWidget::show()</fn>
<dir>/usr/include/qt4/QtGui</dir>
<file>qwidget.h</file>
<line>487</line>
</frame>
<frame>
<ip>0x18C23615</ip>
<obj>/home/milian/projects/compiled/kde4/lib/libkatepartinterfaces.so.4.5.0</obj>
<fn>KateViewInternal::KateViewInternal(KateView*)</fn>
<dir>/home/milian/projects/kde4/kate/part/view</dir>
<file>kateviewinternal.cpp</file>
<line>144</line>
</frame>
<frame>
<ip>0x18C0DA68</ip>
<obj>/home/milian/projects/compiled/kde4/lib/libkatepartinterfaces.so.4.5.0</obj>
<fn>KateView::KateView(KateDocument*, QWidget*)</fn>
<dir>/home/milian/projects/kde4/kate/part/view</dir>
<file>kateview.cpp</file>
<line>136</line>
</frame>
-->
</stack>
<auxwhat>Address 0x11527cb8 is not stack'd, malloc'd or (recently) free'd</auxwhat>
</error>
<status>
<state>FINISHED</state>
<time>00:00:01:49.732 </time>
</status>
<error>
<unique>0x13</unique>
<tid>1</tid>
<kind>Leak_PossiblyLost</kind>
<xwhat>
<text>2 bytes in 1 blocks are possibly lost in loss record 2 of 2,003</text>
<leakedbytes>2</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4C284A8</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so</obj>
<fn>malloc</fn>
<dir>/build/buildd/valgrind-3.6.0~svn20100212/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>236</line>
</frame>
<frame>
<ip>0xD4D7754</ip>
<obj>/lib/libglib-2.0.so.0.2400.1</obj>
<fn>g_malloc</fn>
</frame>
<frame>
<ip>0xD4EF11D</ip>
<obj>/lib/libglib-2.0.so.0.2400.1</obj>
<fn>g_strdup</fn>
</frame>
<frame>
<ip>0xD503DC4</ip>
<obj>/lib/libglib-2.0.so.0.2400.1</obj>
<fn>g_get_language_names</fn>
</frame>
<frame>
<ip>0xD4F89A9</ip>
<obj>/lib/libglib-2.0.so.0.2400.1</obj>
<fn>g_thread_init_glib</fn>
</frame>
<frame>
<ip>0x8396569</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/kernel</dir>
<file>qeventdispatcher_glib.cpp</file>
<line>299</line>
</frame>
<frame>
<ip>0x6ADDBEE</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QGuiEventDispatcherGlibPrivate::QGuiEventDispatcherGlibPrivate()</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qguieventdispatcher_glib.cpp</file>
<line>171</line>
</frame>
<frame>
<ip>0x6ADDCDD</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QGuiEventDispatcherGlib::QGuiEventDispatcherGlib(QObject*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qguieventdispatcher_glib.cpp</file>
<line>186</line>
</frame>
<frame>
<ip>0x6AA5152</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QApplicationPrivate::createEventDispatcher()</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qapplication_x11.cpp</file>
<line>605</line>
</frame>
<frame>
<ip>0x836D069</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QCoreApplication::init()</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/kernel</dir>
<file>qcoreapplication.cpp</file>
<line>552</line>
</frame>
<frame>
<ip>0x836D134</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QCoreApplication::QCoreApplication(QCoreApplicationPrivate&amp;)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/kernel</dir>
<file>qcoreapplication.cpp</file>
<line>477</line>
</frame>
<frame>
<ip>0x6A3815A</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QApplication::QApplication(int&amp;, char**, bool, int)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qapplication.cpp</file>
<line>745</line>
</frame>
</stack>
</error>
<error>
<unique>0x7e4</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>544,542 (56 direct, 544,486 indirect) bytes in 1 blocks are definitely lost in loss record 2,003 of 2,003</text>
<leakedbytes>544542</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4C284A8</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so</obj>
<fn>malloc</fn>
<dir>/build/buildd/valgrind-3.6.0~svn20100212/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>236</line>
</frame>
<frame>
<ip>0x82A1A6C</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QMapData::node_create(QMapData::Node**, int, int)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/tools</dir>
<file>qmap.cpp</file>
<line>140</line>
</frame>
<frame>
<ip>0x8336F68</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QMap&lt;QSettingsKey, QVariant&gt;::detach_helper()</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/../../include/QtCore/../../src/corelib/tools</dir>
<file>qmap.h</file>
<line>449</line>
</frame>
<frame>
<ip>0x832C564</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QConfFile::mergedKeyMap() const</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/../../include/QtCore/../../src/corelib/tools</dir>
<file>qmap.h</file>
<line>202</line>
</frame>
<frame>
<ip>0x833305A</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QConfFileSettingsPrivate::syncConfFile(int)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/io</dir>
<file>qsettings.cpp</file>
<line>1569</line>
</frame>
<frame>
<ip>0x8333D5B</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QConfFileSettingsPrivate::sync()</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/io</dir>
<file>qsettings.cpp</file>
<line>1386</line>
</frame>
<frame>
<ip>0x83260D9</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QSettingsPrivate::update()</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/io</dir>
<file>qsettings.cpp</file>
<line>415</line>
</frame>
<frame>
<ip>0x83267C7</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QSettings::event(QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/io</dir>
<file>qsettings.cpp</file>
<line>3326</line>
</frame>
<frame>
<ip>0x6A2B6EB</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QApplicationPrivate::notify_helper(QObject*, QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qapplication.cpp</file>
<line>4396</line>
</frame>
<frame>
<ip>0x6A311DC</ip>
<obj>/usr/lib/libQtGui.so.4.7.0</obj>
<fn>QApplication::notify(QObject*, QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/gui/kernel</dir>
<file>qapplication.cpp</file>
<line>4277</line>
</frame>
<frame>
<ip>0x6443535</ip>
<obj>/usr/lib/libkdeui.so.5.5.0</obj>
<fn>KApplication::notify(QObject*, QEvent*)</fn>
</frame>
<frame>
<ip>0x83690AB</ip>
<obj>/usr/lib/libQtCore.so.4.7.0</obj>
<fn>QCoreApplication::notifyInternal(QObject*, QEvent*)</fn>
<dir>/build/buildd/qt4-x11-4.7.0/src/corelib/kernel</dir>
<file>qcoreapplication.cpp</file>
<line>732</line>
</frame>
</stack>
</error>
<errorcounts>
<pair>
<count>2</count>
<unique>0x9</unique>
</pair>
</errorcounts>
<suppcounts>
<pair>
<count>12</count>
<name>X on SUSE11 writev uninit padding</name>
</pair>
<pair>
<count>2</count>
<name>dl-hack3-cond-1</name>
</pair>
<pair>
<count>2</count>
<name>glibc-2.5.x-on-SUSE-10.2-(PPC)-2a</name>
</pair>
</suppcounts>
</valgrindoutput>

View File

@@ -55,3 +55,16 @@ FORMS += \
RESOURCES += \ RESOURCES += \
valgrind.qrc valgrind.qrc
equals(TEST, 1) {
DEFINES += "PARSERTESTS_DATA_DIR=\\\"$$_PRO_FILE_PWD_/unit_testdata\\\""
DEFINES += "VALGRIND_FAKE_PATH=\\\"$$IDE_BUILD_TREE/src/tools/valgrindfake\\\""
DEFINES += "TESTRUNNER_SRC_DIR=\\\"$$_PRO_FILE_PWD_/../../../tests/auto/valgrind/memcheck/testapps\\\""
DEFINES += "TESTRUNNER_APP_DIR=\\\"$(PWD)/../../../tests/auto/valgrind/memcheck/testapps\\\""
HEADERS += valgrindmemcheckparsertest.h \
valgrindtestrunnertest.h
SOURCES += valgrindmemcheckparsertest.cpp \
valgrindtestrunnertest.cpp
}

View File

@@ -1,4 +1,5 @@
import qbs 1.0 import qbs
import qbs.FileInfo
QtcPlugin { QtcPlugin {
name: "Valgrind" name: "Valgrind"
@@ -88,4 +89,21 @@ QtcPlugin {
"threadedparser.cpp", "threadedparser.h", "threadedparser.cpp", "threadedparser.h",
] ]
} }
Group {
name: "Test sources"
condition: qtc.testsEnabled
files: [
"valgrindmemcheckparsertest.cpp",
"valgrindmemcheckparsertest.h",
"valgrindtestrunnertest.cpp",
"valgrindtestrunnertest.h",
]
cpp.defines: outer.concat([
'PARSERTESTS_DATA_DIR="' + FileInfo.joinPaths(path, "unit_testdata") + '"',
'VALGRIND_FAKE_PATH="' + FileInfo.joinPaths(project.buildDirectory, qtc.ide_bin_path) + '"',
'TESTRUNNER_SRC_DIR="' + FileInfo.joinPaths(path, "../../../tests/auto/valgrind/memcheck/testapps") + '"',
'TESTRUNNER_APP_DIR="' + FileInfo.joinPaths(project.buildDirectory, qtc.ide_bin_path, "testapps") + '"'
])
}
} }

View File

@@ -24,31 +24,26 @@
** **
****************************************************************************/ ****************************************************************************/
#include <valgrind/xmlprotocol/frame.h> #include "valgrindmemcheckparsertest.h"
#include <valgrind/xmlprotocol/parser.h>
#include <valgrind/xmlprotocol/stack.h>
#include <valgrind/xmlprotocol/suppression.h>
#include "xmlprotocol/frame.h"
#include "xmlprotocol/parser.h"
#include "xmlprotocol/stack.h"
#include "xmlprotocol/suppression.h"
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runnables.h>
#include <extensionsystem/pluginmanager.h>
#include "parsertests.h"
#include <QCoreApplication>
#include <QDebug>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess>
#include <QString> #include <QString>
#include <QTest> #include <QTest>
#include <QTcpServer> #include <QTcpServer>
#include <QTcpSocket> #include <QTcpSocket>
#include <QSignalSpy> #include <QSignalSpy>
#include <iostream>
#include <QProcess>
using namespace Valgrind;
using namespace Valgrind::XmlProtocol; using namespace Valgrind::XmlProtocol;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -64,7 +59,10 @@ inline bool qCompare(int const &t1, MemcheckErrorKind const &t2,
} // namespace QTest } // namespace QTest
QT_END_NAMESPACE QT_END_NAMESPACE
void dumpFrame(const Frame &f) namespace Valgrind {
namespace Test {
static void dumpFrame(const Frame &f)
{ {
qDebug() << f.instructionPointer() << f.directory() << f.fileName() << f.functionName() qDebug() << f.instructionPointer() << f.directory() << f.fileName() << f.functionName()
<< f.line() << f.object(); << f.line() << f.object();
@@ -74,10 +72,10 @@ void dumpError(const Error &e)
{ {
qDebug() << e.kind() << e.leakedBlocks() << e.leakedBytes() << e.what() << e.tid() << e.unique(); qDebug() << e.kind() << e.leakedBlocks() << e.leakedBytes() << e.what() << e.tid() << e.unique();
qDebug() << "stacks:" << e.stacks().size(); qDebug() << "stacks:" << e.stacks().size();
Q_FOREACH(const Stack& s, e.stacks()) { for (const Stack &s : e.stacks()) {
qDebug() << s.auxWhat() << s.directory() << s.file() << s.line() << s.helgrindThreadId(); qDebug() << s.auxWhat() << s.directory() << s.file() << s.line() << s.helgrindThreadId();
qDebug() << "frames:"; qDebug() << "frames:";
Q_FOREACH(const Frame& f, s.frames()) { for (const Frame &f : s.frames()) {
dumpFrame(f); dumpFrame(f);
} }
} }
@@ -85,7 +83,21 @@ void dumpError(const Error &e)
static QString fakeValgrindExecutable() static QString fakeValgrindExecutable()
{ {
return QLatin1String(VALGRIND_FAKE_PATH); QString valgrindFakePath(VALGRIND_FAKE_PATH);
if (Utils::HostOsInfo::isWindowsHost()) {
QFileInfo fi(QString(valgrindFakePath + "/debug"), "valgrind-fake.exe");
if (fi.exists())
return fi.canonicalFilePath();
fi = QFileInfo(QString(valgrindFakePath + "/release"), "valgrind-fake.exe");
if (fi.exists())
return fi.canonicalFilePath();
// Qbs uses the install-root/bin
fi = QFileInfo(valgrindFakePath, "valgrind-fake.exe");
if (fi.exists())
return fi.canonicalFilePath();
qFatal("Neither debug nor release build valgrind-fake found.");
}
return valgrindFakePath + "/valgrind-fake";
} }
static QString dataFile(const QLatin1String &file) static QString dataFile(const QLatin1String &file)
@@ -93,10 +105,8 @@ static QString dataFile(const QLatin1String &file)
return QLatin1String(PARSERTESTS_DATA_DIR) + QLatin1String("/") + file; return QLatin1String(PARSERTESTS_DATA_DIR) + QLatin1String("/") + file;
} }
void ParserTests::initTestCase() void ValgrindMemcheckParserTest::initTestCase()
{ {
new ExtensionSystem::PluginManager;
new ProjectExplorer::ProjectExplorerPlugin;
m_server = new QTcpServer(this); m_server = new QTcpServer(this);
QVERIFY(m_server->listen()); QVERIFY(m_server->listen());
@@ -104,7 +114,7 @@ void ParserTests::initTestCase()
m_process = 0; m_process = 0;
} }
void ParserTests::initTest(const QLatin1String &testfile, const QStringList &otherArgs) void ValgrindMemcheckParserTest::initTest(const QLatin1String &testfile, const QStringList &otherArgs)
{ {
QVERIFY(!m_server->hasPendingConnections()); QVERIFY(!m_server->hasPendingConnections());
@@ -132,7 +142,7 @@ void ParserTests::initTest(const QLatin1String &testfile, const QStringList &oth
QVERIFY(m_socket); QVERIFY(m_socket);
} }
void ParserTests::cleanup() void ValgrindMemcheckParserTest::cleanup()
{ {
if (m_socket) { if (m_socket) {
delete m_socket; delete m_socket;
@@ -144,7 +154,7 @@ void ParserTests::cleanup()
} }
} }
void ParserTests::testHelgrindSample1() void ValgrindMemcheckParserTest::testHelgrindSample1()
{ {
QSKIP("testfile does not exist"); QSKIP("testfile does not exist");
@@ -240,7 +250,7 @@ void ParserTests::testHelgrindSample1()
// QCOMPARE(rec.suppcounts, expectedSuppCounts); // QCOMPARE(rec.suppcounts, expectedSuppCounts);
} }
void ParserTests::testMemcheckSample1() void ValgrindMemcheckParserTest::testMemcheckSample1()
{ {
initTest(QLatin1String("memcheck-output-sample1.xml")); initTest(QLatin1String("memcheck-output-sample1.xml"));
@@ -316,7 +326,7 @@ void ParserTests::testMemcheckSample1()
QCOMPARE(rec.suppcounts, expectedSuppCounts); QCOMPARE(rec.suppcounts, expectedSuppCounts);
} }
void ParserTests::testMemcheckSample2() void ValgrindMemcheckParserTest::testMemcheckSample2()
{ {
QSKIP("testfile does not exist"); QSKIP("testfile does not exist");
@@ -342,7 +352,7 @@ void ParserTests::testMemcheckSample2()
QCOMPARE(stacks.last().auxWhat(), QLatin1String("Address 0x11b66c50 is 0 bytes inside a block of size 16 free'd")); QCOMPARE(stacks.last().auxWhat(), QLatin1String("Address 0x11b66c50 is 0 bytes inside a block of size 16 free'd"));
} }
void ParserTests::testMemcheckSample3() void ValgrindMemcheckParserTest::testMemcheckSample3()
{ {
QSKIP("testfile does not exist"); QSKIP("testfile does not exist");
@@ -394,7 +404,7 @@ void ParserTests::testMemcheckSample3()
QCOMPARE(rec.suppcounts.at(2).second, qint64(3)); QCOMPARE(rec.suppcounts.at(2).second, qint64(3));
} }
void ParserTests::testMemcheckCharm() void ValgrindMemcheckParserTest::testMemcheckCharm()
{ {
QSKIP("testfile does not exist"); QSKIP("testfile does not exist");
@@ -415,7 +425,7 @@ void ParserTests::testMemcheckCharm()
QVERIFY2(parser.errorString().isEmpty(), qPrintable(parser.errorString())); QVERIFY2(parser.errorString().isEmpty(), qPrintable(parser.errorString()));
} }
void ParserTests::testValgrindCrash() void ValgrindMemcheckParserTest::testValgrindCrash()
{ {
initTest(QLatin1String("memcheck-output-sample1.xml"), QStringList() << "--crash"); initTest(QLatin1String("memcheck-output-sample1.xml"), QStringList() << "--crash");
@@ -430,7 +440,7 @@ void ParserTests::testValgrindCrash()
QCOMPARE(parser.errorString(), m_socket->errorString()); QCOMPARE(parser.errorString(), m_socket->errorString());
} }
void ParserTests::testValgrindGarbage() void ValgrindMemcheckParserTest::testValgrindGarbage()
{ {
initTest(QLatin1String("memcheck-output-sample1.xml"), QStringList() << "--garbage"); initTest(QLatin1String("memcheck-output-sample1.xml"), QStringList() << "--garbage");
@@ -444,7 +454,7 @@ void ParserTests::testValgrindGarbage()
qDebug() << parser.errorString(); qDebug() << parser.errorString();
} }
void ParserTests::testParserStop() void ValgrindMemcheckParserTest::testParserStop()
{ {
ThreadedParser parser; ThreadedParser parser;
Memcheck::MemcheckRunner runner; Memcheck::MemcheckRunner runner;
@@ -455,31 +465,39 @@ void ParserTests::testParserStop()
<< "--wait" << "5"); << "--wait" << "5");
runner.setProcessChannelMode(QProcess::ForwardedChannels); runner.setProcessChannelMode(QProcess::ForwardedChannels);
runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)));
runner.start(); runner.start();
QTest::qWait(500); QTest::qWait(500);
runner.stop(); runner.stop();
} }
void ParserTests::testRealValgrind() void ValgrindMemcheckParserTest::testRealValgrind()
{ {
const Utils::Environment &sysEnv = Utils::Environment::systemEnvironment();
auto fileName = sysEnv.searchInPath("valgrind");
if (fileName.isEmpty())
QSKIP("This test needs valgrind in PATH");
QString executable = QProcessEnvironment::systemEnvironment().value("VALGRIND_TEST_BIN", fakeValgrindExecutable()); QString executable = QProcessEnvironment::systemEnvironment().value("VALGRIND_TEST_BIN", fakeValgrindExecutable());
qDebug() << "running exe:" << executable << " HINT: set VALGRIND_TEST_BIN to change this"; qDebug() << "running exe:" << executable << " HINT: set VALGRIND_TEST_BIN to change this";
ThreadedParser parser; ThreadedParser parser;
ProjectExplorer::StandardRunnable debuggee; ProjectExplorer::StandardRunnable debuggee;
debuggee.executable = executable; debuggee.executable = executable;
debuggee.environment = sysEnv;
Memcheck::MemcheckRunner runner; Memcheck::MemcheckRunner runner;
runner.setValgrindExecutable(QLatin1String("valgrind")); runner.setValgrindExecutable(QLatin1String("valgrind"));
runner.setDebuggee(debuggee); runner.setDebuggee(debuggee);
runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)));
runner.setParser(&parser); runner.setParser(&parser);
RunnerDumper dumper(&runner, &parser); RunnerDumper dumper(&runner, &parser);
runner.start(); runner.start();
runner.waitForFinished(); runner.waitForFinished();
} }
void ParserTests::testValgrindStartError_data() void ValgrindMemcheckParserTest::testValgrindStartError_data()
{ {
QTest::addColumn<QString>("valgrindExe"); QTest::addColumn<QString>("valgrindExe");
QTest::addColumn<QStringList>("valgrindArgs"); QTest::addColumn<QStringList>("valgrindArgs");
@@ -497,24 +515,27 @@ void ParserTests::testValgrindStartError_data()
<< fakeValgrindExecutable() << QString(); << fakeValgrindExecutable() << QString();
} }
void ParserTests::testValgrindStartError() void ValgrindMemcheckParserTest::testValgrindStartError()
{ {
QFETCH(QString, valgrindExe); QFETCH(QString, valgrindExe);
QFETCH(QStringList, valgrindArgs); QFETCH(QStringList, valgrindArgs);
QFETCH(QString, debuggeeExecutable); QFETCH(QString, debuggee);
QFETCH(QString, debuggeeArgs); QFETCH(QString, debuggeeArgs);
ThreadedParser parser; ThreadedParser parser;
ProjectExplorer::StandardRunnable debuggee; ProjectExplorer::StandardRunnable debuggeeExecutable;
debuggee.executable = debuggeeExecutable; debuggeeExecutable.executable = debuggee;
debuggee.commandLineArguments = debuggeeArgs; debuggeeExecutable.environment = Utils::Environment::systemEnvironment();
debuggeeExecutable.commandLineArguments = debuggeeArgs;
Memcheck::MemcheckRunner runner; Memcheck::MemcheckRunner runner;
runner.setParser(&parser); runner.setParser(&parser);
runner.setValgrindExecutable(valgrindExe); runner.setValgrindExecutable(valgrindExe);
runner.setValgrindArguments(valgrindArgs); runner.setValgrindArguments(valgrindArgs);
runner.setDebuggee(debuggee); runner.setDebuggee(debuggeeExecutable);
runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)));
RunnerDumper dumper(&runner, &parser); RunnerDumper dumper(&runner, &parser);
runner.start(); runner.start();
runner.waitForFinished(); runner.waitForFinished();
@@ -522,4 +543,5 @@ void ParserTests::testValgrindStartError()
// just finish without deadlock and we are fine // just finish without deadlock and we are fine
} }
QTEST_MAIN(ParserTests) } // namespace Test
} // namespace Valgrind

View File

@@ -32,11 +32,11 @@
#include <QVector> #include <QVector>
#include <QDebug> #include <QDebug>
#include <valgrind/xmlprotocol/error.h> #include "xmlprotocol/error.h"
#include <valgrind/xmlprotocol/status.h> #include "xmlprotocol/status.h"
#include <valgrind/xmlprotocol/threadedparser.h> #include "xmlprotocol/threadedparser.h"
#include <valgrind/xmlprotocol/parser.h> #include "xmlprotocol/parser.h"
#include <valgrind/memcheck/memcheckrunner.h> #include "memcheck/memcheckrunner.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QTcpServer; class QTcpServer;
@@ -44,6 +44,10 @@ class QTcpSocket;
class QProcess; class QProcess;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Valgrind {
namespace Test {
void dumpError(const Valgrind::XmlProtocol::Error &e); void dumpError(const Valgrind::XmlProtocol::Error &e);
class Recorder : public QObject class Recorder : public QObject
@@ -134,7 +138,7 @@ public:
}; };
class ParserTests : public QObject class ValgrindMemcheckParserTest : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -159,7 +163,10 @@ private Q_SLOTS:
private: private:
void initTest(const QLatin1String &testfile, const QStringList &otherArgs = QStringList()); void initTest(const QLatin1String &testfile, const QStringList &otherArgs = QStringList());
QTcpServer *m_server; QTcpServer *m_server = 0;
QProcess *m_process; QProcess *m_process = 0;
QTcpSocket *m_socket; QTcpSocket *m_socket = 0;
}; };
} // namespace Test
} // namespace Valgrind

View File

@@ -32,6 +32,11 @@
#include "valgrindsettings.h" #include "valgrindsettings.h"
#include "valgrindconfigwidget.h" #include "valgrindconfigwidget.h"
#ifdef WITH_TESTS
# include "valgrindmemcheckparsertest.h"
# include "valgrindtestrunnertest.h"
#endif
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -117,5 +122,14 @@ ValgrindGlobalSettings *ValgrindPlugin::globalSettings()
return theGlobalSettings; return theGlobalSettings;
} }
QList<QObject *> ValgrindPlugin::createTestObjects() const
{
QList<QObject *> tests;
#ifdef WITH_TESTS
tests << new Test::ValgrindMemcheckParserTest << new Test::ValgrindTestRunnerTest;
#endif
return tests;
}
} // namespace Internal } // namespace Internal
} // namespace Valgrind } // namespace Valgrind

View File

@@ -48,6 +48,8 @@ public:
ShutdownFlag aboutToShutdown() override; ShutdownFlag aboutToShutdown() override;
static ValgrindGlobalSettings *globalSettings(); static ValgrindGlobalSettings *globalSettings();
private:
QList<QObject *> createTestObjects() const override;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -24,76 +24,78 @@
** **
****************************************************************************/ ****************************************************************************/
#include "testrunner.h" #include "valgrindtestrunnertest.h"
#include <valgrind/xmlprotocol/frame.h> #include "xmlprotocol/frame.h"
#include <valgrind/xmlprotocol/stack.h> #include "xmlprotocol/stack.h"
#include <valgrind/xmlprotocol/suppression.h> #include "xmlprotocol/suppression.h"
#include <valgrind/xmlprotocol/threadedparser.h> #include "xmlprotocol/threadedparser.h"
#include <valgrind/xmlprotocol/parser.h> #include "xmlprotocol/parser.h"
#include <valgrind/memcheck/memcheckrunner.h> #include "memcheck/memcheckrunner.h"
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runnables.h>
#include <extensionsystem/pluginmanager.h>
#include <QDebug> #include <QDebug>
#include <QTest> #include <QTest>
#include <QDir> #include <QDir>
#include <QSignalSpy> #include <QSignalSpy>
const QString appSrcDir(TESTRUNNER_SRC_DIR); #define HEADER_LENGTH 25
const QString appBinDir(TESTRUNNER_APP_DIR);
#define HEADER_LENGTH 30 using namespace Valgrind::XmlProtocol;
using namespace Valgrind::Memcheck;
bool on64bit() namespace Valgrind {
namespace Test {
//BEGIN Test Helpers and boilerplate code
static const QString appSrcDir(TESTRUNNER_SRC_DIR);
static const QString appBinDir(TESTRUNNER_APP_DIR);
static bool on64bit()
{ {
return sizeof(char*) == 8; return sizeof(char*) == 8;
} }
QString srcDirForApp(const QString &app) static QString srcDirForApp(const QString &app)
{ {
return appSrcDir + QLatin1Char('/') + app; return QDir::cleanPath(appSrcDir + QLatin1Char('/') + app);
} }
QTEST_MAIN(Valgrind::TestRunner) ValgrindTestRunnerTest::ValgrindTestRunnerTest(QObject *parent)
: QObject(parent)
using namespace Valgrind;
using namespace Valgrind::XmlProtocol;
using namespace Valgrind::Memcheck;
//BEGIN Test Helpers and boilerplate code
TestRunner::TestRunner(QObject *parent)
: QObject(parent),
m_parser(0),
m_runner(0)
{ {
qRegisterMetaType<Error>(); qRegisterMetaType<Error>();
} }
QString TestRunner::runTestBinary(const QString &binary, const QStringList &vArgs) QString ValgrindTestRunnerTest::runTestBinary(const QString &binary, const QStringList &vArgs)
{ {
const QString binPath = appBinDir + QLatin1Char('/') + binary; const QFileInfo binPathFileInfo(appBinDir, binary);
if (!QFileInfo(binPath).isExecutable()) if (!binPathFileInfo.isExecutable())
qFatal("No such test app: %s", qPrintable(binPath)); return QString();
ProjectExplorer::StandardRunnable debuggee; ProjectExplorer::StandardRunnable debuggee;
const QString &binPath = binPathFileInfo.canonicalFilePath();
debuggee.executable = binPath; debuggee.executable = binPath;
debuggee.environment = Utils::Environment::systemEnvironment();
m_runner->setValgrindArguments(QStringList() << "--num-callers=50" << "--track-origins=yes" << vArgs); m_runner->setValgrindArguments(QStringList() << "--num-callers=50" << "--track-origins=yes" << vArgs);
m_runner->setDebuggee(debuggee); m_runner->setDebuggee(debuggee);
m_runner->setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)));
m_runner->start(); m_runner->start();
m_runner->waitForFinished(); m_runner->waitForFinished();
return binPath; return binPath;
} }
void TestRunner::logMessageReceived(const QByteArray &message) void ValgrindTestRunnerTest::logMessageReceived(const QByteArray &message)
{ {
qDebug() << "log message received:" << message; qDebug() << "log message received:" << message;
m_logMessages << message; m_logMessages << message;
} }
void TestRunner::internalError(const QString &error) void ValgrindTestRunnerTest::internalError(const QString &error)
{ {
if (!m_expectCrash) if (!m_expectCrash)
QFAIL(qPrintable(error)); QFAIL(qPrintable(error));
@@ -101,12 +103,12 @@ void TestRunner::internalError(const QString &error)
qDebug() << "expected crash:" << error; qDebug() << "expected crash:" << error;
} }
void TestRunner::error(const Error &error) void ValgrindTestRunnerTest::error(const Error &error)
{ {
m_errors << error; m_errors << error;
} }
void TestRunner::cleanup() void ValgrindTestRunnerTest::cleanup()
{ {
Q_ASSERT(m_runner); Q_ASSERT(m_runner);
delete m_runner; delete m_runner;
@@ -120,14 +122,12 @@ void TestRunner::cleanup()
m_expectCrash = false; m_expectCrash = false;
} }
void TestRunner::initTestCase() void ValgrindTestRunnerTest::init()
{
new ExtensionSystem::PluginManager;
new ProjectExplorer::ProjectExplorerPlugin;
}
void TestRunner::init()
{ {
const Utils::Environment &sysEnv = Utils::Environment::systemEnvironment();
auto fileName = sysEnv.searchInPath("valgrind");
if (fileName.isEmpty())
QSKIP("This test needs valgrind in PATH");
Q_ASSERT(m_logMessages.isEmpty()); Q_ASSERT(m_logMessages.isEmpty());
Q_ASSERT(!m_runner); Q_ASSERT(!m_runner);
@@ -135,24 +135,27 @@ void TestRunner::init()
m_runner->setValgrindExecutable(QLatin1String("valgrind")); m_runner->setValgrindExecutable(QLatin1String("valgrind"));
m_runner->setProcessChannelMode(QProcess::ForwardedChannels); m_runner->setProcessChannelMode(QProcess::ForwardedChannels);
connect(m_runner, &MemcheckRunner::logMessageReceived, connect(m_runner, &MemcheckRunner::logMessageReceived,
this, &TestRunner::logMessageReceived); this, &ValgrindTestRunnerTest::logMessageReceived);
connect(m_runner, &ValgrindRunner::processErrorReceived, connect(m_runner, &ValgrindRunner::processErrorReceived,
this, &TestRunner::internalError); this, &ValgrindTestRunnerTest::internalError);
Q_ASSERT(!m_parser); Q_ASSERT(!m_parser);
m_parser = new ThreadedParser; m_parser = new ThreadedParser;
connect(m_parser, &ThreadedParser::internalError, connect(m_parser, &ThreadedParser::internalError,
this, &TestRunner::internalError); this, &ValgrindTestRunnerTest::internalError);
connect(m_parser, &ThreadedParser::error, connect(m_parser, &ThreadedParser::error,
this, &TestRunner::error); this, &ValgrindTestRunnerTest::error);
m_runner->setParser(m_parser); m_runner->setParser(m_parser);
} }
//BEGIN: Actual test cases //BEGIN: Actual test cases
void TestRunner::testLeak1() void ValgrindTestRunnerTest::testLeak1()
{ {
const QString binary = runTestBinary(QLatin1String("leak1/leak1")); const QString binary = runTestBinary(QLatin1String("leak1/leak1"));
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -183,9 +186,12 @@ void TestRunner::testLeak1()
} }
} }
void TestRunner::testLeak2() void ValgrindTestRunnerTest::testLeak2()
{ {
const QString binary = runTestBinary(QLatin1String("leak2/leak2")); const QString binary = runTestBinary(QLatin1String("leak2/leak2"));
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
QCOMPARE(m_errors.count(), 1); QCOMPARE(m_errors.count(), 1);
@@ -220,10 +226,12 @@ void TestRunner::testLeak2()
} }
} }
void TestRunner::testLeak3() void ValgrindTestRunnerTest::testLeak3()
{ {
const QString binary = runTestBinary(QLatin1String("leak3/leak3"), QStringList() << "--show-reachable=yes"); const QString binary = runTestBinary(QLatin1String("leak3/leak3"), QStringList() << "--show-reachable=yes");
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
QCOMPARE(m_errors.count(), 1); QCOMPARE(m_errors.count(), 1);
@@ -258,16 +266,19 @@ void TestRunner::testLeak3()
} }
} }
void TestRunner::testLeak4() void ValgrindTestRunnerTest::testLeak4()
{ {
const QString app("leak4"); const QString app("leak4");
const QString binary = runTestBinary(app + QLatin1Char('/') + app, const QString binary = runTestBinary(app + QLatin1Char('/') + app,
QStringList() << "--show-reachable=yes"); QStringList() << "--show-reachable=yes");
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp("leak4"); const QString srcDir = srcDirForApp("leak4");
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
QCOMPARE(m_errors.count(), 2); QCOMPARE(m_errors.count(), 3);
//BEGIN first error //BEGIN first error
{ {
const Error error = m_errors.first(); const Error error = m_errors.first();
@@ -306,7 +317,7 @@ void TestRunner::testLeak4()
} }
//BEGIN second error //BEGIN second error
{ {
const Error error = m_errors.last(); const Error error = m_errors.at(1);
QCOMPARE(error.kind(), int(Leak_DefinitelyLost)); QCOMPARE(error.kind(), int(Leak_DefinitelyLost));
QCOMPARE(error.leakedBlocks(), qint64(1)); QCOMPARE(error.leakedBlocks(), qint64(1));
if (on64bit()) if (on64bit())
@@ -334,12 +345,16 @@ void TestRunner::testLeak4()
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
} }
} }
// TODO add third error check
} }
void TestRunner::uninit1() void ValgrindTestRunnerTest::testUninit1()
{ {
const QString app("uninit1"); const QString app("uninit1");
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -378,11 +393,14 @@ void TestRunner::uninit1()
} }
} }
void TestRunner::uninit2() void ValgrindTestRunnerTest::testUninit2()
{ {
const QString app("uninit2"); const QString app("uninit2");
m_expectCrash = true; m_expectCrash = true;
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -442,11 +460,14 @@ void TestRunner::uninit2()
} }
} }
void TestRunner::uninit3() void ValgrindTestRunnerTest::testUninit3()
{ {
const QString app("uninit3"); const QString app("uninit3");
m_expectCrash = true; m_expectCrash = true;
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -506,10 +527,13 @@ void TestRunner::uninit3()
} }
} }
void TestRunner::syscall() void ValgrindTestRunnerTest::testSyscall()
{ {
const QString app("syscall"); const QString app("syscall");
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -565,10 +589,13 @@ void TestRunner::syscall()
} }
} }
void TestRunner::free1() void ValgrindTestRunnerTest::testFree1()
{ {
const QString app("free1"); const QString app("free1");
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -619,10 +646,13 @@ void TestRunner::free1()
} }
} }
void TestRunner::free2() void ValgrindTestRunnerTest::testFree2()
{ {
const QString app("free2"); const QString app("free2");
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -677,12 +707,14 @@ void TestRunner::free2()
} }
} }
void TestRunner::invalidjump() void ValgrindTestRunnerTest::testInvalidjump()
{ {
const QString app("invalidjump"); const QString app("invalidjump");
m_expectCrash = true; m_expectCrash = true;
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
const QString srcDir = srcDirForApp(app); if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -705,11 +737,14 @@ void TestRunner::invalidjump()
} }
void TestRunner::overlap() void ValgrindTestRunnerTest::testOverlap()
{ {
const QString app("overlap"); const QString app("overlap");
m_expectCrash = true; m_expectCrash = true;
const QString binary = runTestBinary(app + QLatin1Char('/') + app); const QString binary = runTestBinary(app + QLatin1Char('/') + app);
if (binary.isEmpty())
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
"manually before executing this test.");
const QString srcDir = srcDirForApp(app); const QString srcDir = srcDirForApp(app);
QVERIFY(m_logMessages.isEmpty()); QVERIFY(m_logMessages.isEmpty());
@@ -735,3 +770,6 @@ void TestRunner::overlap()
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
} }
} }
} // namespace Test
} // namespace Valgrind

View File

@@ -29,7 +29,7 @@
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <valgrind/xmlprotocol/error.h> #include "xmlprotocol/error.h"
namespace Valgrind { namespace Valgrind {
@@ -41,15 +41,16 @@ namespace Memcheck {
class MemcheckRunner; class MemcheckRunner;
} }
class TestRunner : public QObject namespace Test {
class ValgrindTestRunnerTest : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TestRunner(QObject *parent = 0); explicit ValgrindTestRunnerTest(QObject *parent = 0);
private Q_SLOTS: private slots:
void initTestCase();
void init(); void init();
void cleanup(); void cleanup();
@@ -58,18 +59,17 @@ private Q_SLOTS:
void testLeak3(); void testLeak3();
void testLeak4(); void testLeak4();
void uninit1(); void testUninit1();
void uninit2(); void testUninit2();
void uninit3(); void testUninit3();
void free1(); void testFree1();
void free2(); void testFree2();
void invalidjump(); void testInvalidjump();
void syscall(); void testSyscall();
void overlap(); void testOverlap();
private Q_SLOTS:
void logMessageReceived(const QByteArray &message); void logMessageReceived(const QByteArray &message);
void internalError(const QString &error); void internalError(const QString &error);
void error(const Valgrind::XmlProtocol::Error &error); void error(const Valgrind::XmlProtocol::Error &error);
@@ -77,11 +77,12 @@ private Q_SLOTS:
private: private:
QString runTestBinary(const QString &binary, const QStringList &vArgs = QStringList()); QString runTestBinary(const QString &binary, const QStringList &vArgs = QStringList());
XmlProtocol::ThreadedParser *m_parser; XmlProtocol::ThreadedParser *m_parser = 0;
Memcheck::MemcheckRunner *m_runner; Memcheck::MemcheckRunner *m_runner = 0;
QList<QByteArray> m_logMessages; QList<QByteArray> m_logMessages;
QList<XmlProtocol::Error> m_errors; QList<XmlProtocol::Error> m_errors;
bool m_expectCrash; bool m_expectCrash = false;
}; };
} // namespace Test
} // namespace Valgrind } // namespace Valgrind

View File

@@ -140,8 +140,10 @@ bool AddToolChainOperation::setArguments(const QStringList &args)
if (m_id.isEmpty()) if (m_id.isEmpty())
std::cerr << "No id given for tool chain." << std::endl; std::cerr << "No id given for tool chain." << std::endl;
if (m_languageId.isEmpty()) if (m_languageId.isEmpty()) {
std::cerr << "No language id given for tool chain." << std::endl; std::cerr << "No language id given for tool chain." << std::endl;
m_languageId = "2";
}
if (m_displayName.isEmpty()) if (m_displayName.isEmpty())
std::cerr << "No name given for tool chain." << std::endl; std::cerr << "No name given for tool chain." << std::endl;
if (m_path.isEmpty()) if (m_path.isEmpty())

View File

@@ -1881,7 +1881,6 @@ void tst_Dumpers::dumper_data()
"unused(&dir, &s, &fi);\n") "unused(&dir, &s, &fi);\n")
+ CoreProfile() + CoreProfile()
+ UseDebugImage()
+ QtVersion(0x50300) + QtVersion(0x50300)
+ Check("dir", tempDir, "@QDir") + Check("dir", tempDir, "@QDir")
@@ -2530,7 +2529,6 @@ void tst_Dumpers::dumper_data()
"child.setObjectName(\"A renamed Child\");\n") "child.setObjectName(\"A renamed Child\");\n")
+ CoreProfile() + CoreProfile()
+ UseDebugImage() // FIXME: Avoid the need. Needed for LLDB object name.
+ Check("child", "\"A renamed Child\"", "@QObject") + Check("child", "\"A renamed Child\"", "@QObject")
+ Check("parent", "\"A Parent\"", "@QObject"); + Check("parent", "\"A Parent\"", "@QObject");
@@ -2647,7 +2645,6 @@ void tst_Dumpers::dumper_data()
"unused(&ob, &ob1, &ob2);\n") "unused(&ob, &ob1, &ob2);\n")
+ GuiProfile() + GuiProfile()
+ UseDebugImage() // FIXME: Needed for QObject name
+ Check("ob", "\"An Object\"", "@QWidget") + Check("ob", "\"An Object\"", "@QWidget")
+ Check("ob1", "\"Another Object\"", "@QObject") + Check("ob1", "\"Another Object\"", "@QObject")
@@ -2778,7 +2775,6 @@ void tst_Dumpers::dumper_data()
"int pos2 = re.indexIn(str2); unused(&pos2);\n" "int pos2 = re.indexIn(str2); unused(&pos2);\n"
"QStringList caps = re.capturedTexts(); unused(&caps);\n") "QStringList caps = re.capturedTexts(); unused(&caps);\n")
+ CoreProfile() + CoreProfile()
+ UseDebugImage()
+ Check("re", "\"a(.*)b(.*)c\"", "@QRegExp") + Check("re", "\"a(.*)b(.*)c\"", "@QRegExp")
+ Check("re.captures.0", "[0]", "\"a1121b344c\"", "@QString") + Check("re.captures.0", "[0]", "\"a1121b344c\"", "@QString")
+ Check("re.captures.1", "[1]", "\"1121\"", "@QString") + Check("re.captures.1", "[1]", "\"1121\"", "@QString")
@@ -2850,7 +2846,6 @@ void tst_Dumpers::dumper_data()
"unused(&region0, &region1, &region2, &rects);\n") "unused(&region0, &region1, &region2, &rects);\n")
+ GuiProfile() + GuiProfile()
+ UseDebugImage()
+ Check("region0", "<0 items>", "@QRegion") + Check("region0", "<0 items>", "@QRegion")
+ Check("region1", "<1 items>", "@QRegion") + Check("region1", "<1 items>", "@QRegion")
@@ -3438,7 +3433,6 @@ void tst_Dumpers::dumper_data()
"}\n") "}\n")
+ CoreProfile() + CoreProfile()
+ UseDebugImage()
+ CheckType("this", "Thread") + CheckType("this", "Thread")
+ Check("this.@1", "[@QThread]", "\"This is thread #3\"", "@QThread"); + Check("this.@1", "[@QThread]", "\"This is thread #3\"", "@QThread");
@@ -3700,7 +3694,6 @@ void tst_Dumpers::dumper_data()
"unused(&ha1);\n") "unused(&ha1);\n")
+ NetworkProfile() + NetworkProfile()
+ UseDebugImage()
+ Check("ha", "\"127.0.0.1\"", "@QHostAddress") + Check("ha", "\"127.0.0.1\"", "@QHostAddress")
+ Check("ha.a", "2130706433", TypeDef("unsigned int", "@quint32")) + Check("ha.a", "2130706433", TypeDef("unsigned int", "@quint32"))
@@ -5948,7 +5941,6 @@ void tst_Dumpers::dumper_data()
+ CoreProfile() + CoreProfile()
+ QtVersion(0x50000) + QtVersion(0x50000)
+ UseDebugImage()
+ Check("file", "\"A file\"", "MyFile") + Check("file", "\"A file\"", "MyFile")
+ Check("file.@1", "[@QFile]", "\"/tmp/tt\"", "@QFile"); + Check("file.@1", "[@QFile]", "\"/tmp/tt\"", "@QFile");
@@ -6472,6 +6464,17 @@ void tst_Dumpers::dumper_data()
"QtcDumperTest_FieldAccessByIndex d; unused(&d);\n") "QtcDumperTest_FieldAccessByIndex d; unused(&d);\n")
+ Check("d", "12", "QtcDumperTest_FieldAccessByIndex"); + Check("d", "12", "QtcDumperTest_FieldAccessByIndex");
QTest::newRow("Internal2")
<< Data("struct Foo { int bar = 15; }; \n"
"struct QtcDumperTest_PointerArray {\n"
" Foo *foos = new Foo[10];\n"
"};\n\n",
"QtcDumperTest_PointerArray tc; unused(&tc);\n")
+ Check("tc.0.bar", "15", "int")
+ Check("tc.1.bar", "15", "int")
+ Check("tc.2.bar", "15", "int")
+ Check("tc.3.bar", "15", "int");
#if 0 #if 0
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
// Hint: To open a failing test in Creator, do: // Hint: To open a failing test in Creator, do:

View File

@@ -1,984 +0,0 @@
<?xml version="1.0"?>
<valgrindoutput>
<protocolversion>4</protocolversion>
<protocoltool>memcheck</protocoltool>
<preamble>
<line>Memcheck, a memory error detector</line>
<line>Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.</line>
<line>Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info</line>
<line>Command: /home/chris/untitled/untitled</line>
</preamble>
<pid>20854</pid>
<ppid>20386</ppid>
<tool>memcheck</tool>
<args>
<vargv>
<exe>/usr/bin/valgrind.bin</exe>
<arg>--suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp</arg>
<arg>--xml=yes</arg>
<arg>--xml-file=/tmp/bla</arg>
</vargv>
<argv>
<exe>/home/chris/untitled/untitled</exe>
</argv>
</args>
<status>
<state>RUNNING</state>
<time>00:00:00:00.161 </time>
</status>
<status>
<state>FINISHED</state>
<time>00:00:00:12.379 </time>
</status>
<error>
<unique>0x107</unique>
<tid>1</tid>
<kind>Leak_PossiblyLost</kind>
<xwhat>
<text>120 bytes in 1 blocks are possibly lost in loss record 184 of 270</text>
<leakedbytes>120</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402517B</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>memalign</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>581</line>
</frame>
<frame>
<ip>0x40251D8</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>posix_memalign</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>709</line>
</frame>
<frame>
<ip>0x42BE546</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
</frame>
<frame>
<ip>0x42BFA2F</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_slice_alloc</fn>
</frame>
<frame>
<ip>0x42C06DD</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_slist_prepend</fn>
</frame>
<frame>
<ip>0x42C368E</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_strsplit</fn>
</frame>
<frame>
<ip>0x42D9393</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_get_language_names</fn>
</frame>
<frame>
<ip>0x42D98E6</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
</frame>
<frame>
<ip>0x42CB919</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_thread_init_glib</fn>
</frame>
<frame>
<ip>0x4254506</ip>
<obj>/usr/lib/i386-linux-gnu/libgthread-2.0.so.0.2800.6</obj>
<fn>g_thread_init</fn>
</frame>
<frame>
<ip>0x8D4D458</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*)</fn>
</frame>
<frame>
<ip>0x85C7CA5</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QGuiEventDispatcherGlibPrivate::QGuiEventDispatcherGlibPrivate()</fn>
</frame>
</stack>
</error>
<error>
<unique>0x109</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>122 (56 direct, 66 indirect) bytes in 1 blocks are definitely lost in loss record 186 of 270</text>
<leakedbytes>122</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402641D</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>operator new(unsigned int)</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>255</line>
</frame>
<frame>
<ip>0x8D0FC45</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibraryPrivate::findOrCreate(QString const&amp;, QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8D10347</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::setFileNameAndVersion(QString const&amp;, int)</fn>
</frame>
<frame>
<ip>0x8D10404</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::QLibrary(QString const&amp;, int, QObject*)</fn>
</frame>
<frame>
<ip>0x859BD96</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_load_library_runtime(char const*, int, int, char const*)</fn>
</frame>
<frame>
<ip>0x859C93C</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_init(QApplicationPrivate*, int, _XDisplay*, unsigned long, unsigned long)</fn>
</frame>
<frame>
<ip>0x853EEDC</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplicationPrivate::construct(_XDisplay*, unsigned long, unsigned long)</fn>
</frame>
<frame>
<ip>0x853F766</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplication::QApplication(int&amp;, char**, int)</fn>
</frame>
<frame>
<ip>0x805209E</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>createApplication(int&amp;, char**)</fn>
<dir>/home/chris/untitled/qmlapplicationviewer</dir>
<file>qmlapplicationviewer.cpp</file>
<line>175</line>
</frame>
<frame>
<ip>0x805185F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>main</fn>
<dir>/home/chris/untitled</dir>
<file>main.cpp</file>
<line>6</line>
</frame>
</stack>
</error>
<error>
<unique>0x10a</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>124 bytes in 1 blocks are definitely lost in loss record 187 of 270</text>
<leakedbytes>124</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4026864</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>malloc</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>236</line>
</frame>
<frame>
<ip>0x4635902</ip>
<obj>/usr/lib/i386-linux-gnu/libxcb.so.1.1.0</obj>
<fn>get_peer_sock_name</fn>
<dir>/build/buildd/libxcb-1.7/obj-i686-linux-gnu/src/../../src</dir>
<file>xcb_auth.c</file>
<line>259</line>
</frame>
<frame>
<ip>0x4635A04</ip>
<obj>/usr/lib/i386-linux-gnu/libxcb.so.1.1.0</obj>
<fn>_xcb_get_auth_info</fn>
<dir>/build/buildd/libxcb-1.7/obj-i686-linux-gnu/src/../../src</dir>
<file>xcb_auth.c</file>
<line>302</line>
</frame>
<frame>
<ip>0x46353D1</ip>
<obj>/usr/lib/i386-linux-gnu/libxcb.so.1.1.0</obj>
<fn>xcb_connect_to_display_with_auth_info</fn>
<dir>/build/buildd/libxcb-1.7/obj-i686-linux-gnu/src/../../src</dir>
<file>xcb_util.c</file>
<line>424</line>
</frame>
<frame>
<ip>0x46355DB</ip>
<obj>/usr/lib/i386-linux-gnu/libxcb.so.1.1.0</obj>
<fn>xcb_connect</fn>
<dir>/build/buildd/libxcb-1.7/obj-i686-linux-gnu/src/../../src</dir>
<file>xcb_util.c</file>
<line>395</line>
</frame>
<frame>
<ip>0x4169A22</ip>
<obj>/usr/lib/i386-linux-gnu/libX11.so.6.3.0</obj>
<fn>_XConnectXCB</fn>
</frame>
<frame>
<ip>0x41598F3</ip>
<obj>/usr/lib/i386-linux-gnu/libX11.so.6.3.0</obj>
<fn>XOpenDisplay</fn>
</frame>
<frame>
<ip>0x859E45F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_init(QApplicationPrivate*, int, _XDisplay*, unsigned long, unsigned long)</fn>
</frame>
<frame>
<ip>0x853EEDC</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplicationPrivate::construct(_XDisplay*, unsigned long, unsigned long)</fn>
</frame>
<frame>
<ip>0x853F766</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplication::QApplication(int&amp;, char**, int)</fn>
</frame>
<frame>
<ip>0x805209E</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>createApplication(int&amp;, char**)</fn>
<dir>/home/chris/untitled/qmlapplicationviewer</dir>
<file>qmlapplicationviewer.cpp</file>
<line>175</line>
</frame>
<frame>
<ip>0x805185F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>main</fn>
<dir>/home/chris/untitled</dir>
<file>main.cpp</file>
<line>6</line>
</frame>
</stack>
</error>
<error>
<unique>0x10f</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>138 (56 direct, 82 indirect) bytes in 1 blocks are definitely lost in loss record 192 of 270</text>
<leakedbytes>138</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402641D</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>operator new(unsigned int)</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>255</line>
</frame>
<frame>
<ip>0x8D0FC45</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibraryPrivate::findOrCreate(QString const&amp;, QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8D10347</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::setFileNameAndVersion(QString const&amp;, int)</fn>
</frame>
<frame>
<ip>0x8D10404</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::QLibrary(QString const&amp;, int, QObject*)</fn>
</frame>
<frame>
<ip>0x859BD96</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_load_library_runtime(char const*, int, int, char const*)</fn>
</frame>
<frame>
<ip>0x859DE94</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_init(QApplicationPrivate*, int, _XDisplay*, unsigned long, unsigned long)</fn>
</frame>
<frame>
<ip>0x853EEDC</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplicationPrivate::construct(_XDisplay*, unsigned long, unsigned long)</fn>
</frame>
<frame>
<ip>0x853F766</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplication::QApplication(int&amp;, char**, int)</fn>
</frame>
<frame>
<ip>0x805209E</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>createApplication(int&amp;, char**)</fn>
<dir>/home/chris/untitled/qmlapplicationviewer</dir>
<file>qmlapplicationviewer.cpp</file>
<line>175</line>
</frame>
<frame>
<ip>0x805185F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>main</fn>
<dir>/home/chris/untitled</dir>
<file>main.cpp</file>
<line>6</line>
</frame>
</stack>
</error>
<error>
<unique>0x114</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>158 (56 direct, 102 indirect) bytes in 1 blocks are definitely lost in loss record 197 of 270</text>
<leakedbytes>158</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402641D</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>operator new(unsigned int)</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>255</line>
</frame>
<frame>
<ip>0x8D0FC45</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibraryPrivate::findOrCreate(QString const&amp;, QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8D1023F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::setFileNameAndVersion(QString const&amp;, QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8D102A4</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::QLibrary(QString const&amp;, QString const&amp;, QObject*)</fn>
</frame>
<frame>
<ip>0x8C8FCCD</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_initIcu(QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8C4B0CF</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLocalePrivate::updateSystemPrivate()</fn>
</frame>
<frame>
<ip>0x8C4B3C6</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>systemPrivate()</fn>
</frame>
<frame>
<ip>0x8C4B40C</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>defaultPrivate()</fn>
</frame>
<frame>
<ip>0x8C4B55F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLocale::QLocale()</fn>
</frame>
<frame>
<ip>0x8CCF6F3</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QResourceFileEngine::QResourceFileEngine(QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8CF87DC</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>_q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry&amp;, QFileSystemMetaData&amp;, QAbstractFileEngine*&amp;, bool)</fn>
</frame>
<frame>
<ip>0x8CF8947</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QFileSystemEngine::resolveEntryAndCreateLegacyEngine(QFileSystemEntry&amp;, QFileSystemMetaData&amp;)</fn>
</frame>
</stack>
</error>
<error>
<unique>0x116</unique>
<tid>1</tid>
<kind>Leak_PossiblyLost</kind>
<xwhat>
<text>160 bytes in 1 blocks are possibly lost in loss record 199 of 270</text>
<leakedbytes>160</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4025315</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>calloc</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>467</line>
</frame>
<frame>
<ip>0x4010CD7</ip>
<obj>/lib/i386-linux-gnu/ld-2.13.so</obj>
<fn>allocate_dtv</fn>
<dir>/build/buildd/eglibc-2.13/elf</dir>
<file>dl-tls.c</file>
<line>300</line>
</frame>
<frame>
<ip>0x401146B</ip>
<obj>/lib/i386-linux-gnu/ld-2.13.so</obj>
<fn>_dl_allocate_tls</fn>
<dir>/build/buildd/eglibc-2.13/elf</dir>
<file>dl-tls.c</file>
<line>464</line>
</frame>
<frame>
<ip>0x433E5C6</ip>
<obj>/lib/i386-linux-gnu/libpthread-2.13.so</obj>
<fn>pthread_create@@GLIBC_2.1</fn>
<dir>/build/buildd/eglibc-2.13/nptl</dir>
<file>allocatestack.c</file>
<line>570</line>
</frame>
<frame>
<ip>0x83A6BED</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QTWTF::TCMalloc_PageHeap::initializeScavenger()</fn>
</frame>
<frame>
<ip>0x83A92E9</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QTWTF::TCMalloc_ThreadCache::InitModule()</fn>
</frame>
<frame>
<ip>0x83AA188</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QTWTF::fastMalloc(unsigned int)</fn>
</frame>
<frame>
<ip>0x83AEE4B</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QTWTF::initializeThreading()</fn>
</frame>
<frame>
<ip>0x8338CBF</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QTJSC::initializeThreading()</fn>
</frame>
<frame>
<ip>0x82897BE</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QScriptEnginePrivate::QScriptEnginePrivate()</fn>
</frame>
<frame>
<ip>0x828AAB2</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QScriptEngine::QScriptEngine()</fn>
</frame>
<frame>
<ip>0x8063261</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate*)</fn>
</frame>
</stack>
</error>
<error>
<unique>0x117</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>160 (40 direct, 120 indirect) bytes in 1 blocks are definitely lost in loss record 200 of 270</text>
<leakedbytes>160</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4026864</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>malloc</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>236</line>
</frame>
<frame>
<ip>0x4565FAB</ip>
<obj>/lib/i386-linux-gnu/libc-2.13.so</obj>
<fn>nss_parse_service_list</fn>
<dir>/build/buildd/eglibc-2.13/nss</dir>
<file>nsswitch.c</file>
<line>626</line>
</frame>
<frame>
<ip>0x4566584</ip>
<obj>/lib/i386-linux-gnu/libc-2.13.so</obj>
<fn>__nss_database_lookup</fn>
<dir>/build/buildd/eglibc-2.13/nss</dir>
<file>nsswitch.c</file>
<line>167</line>
</frame>
<frame>
<ip>0x6BAAE9B</ip>
</frame>
<frame>
<ip>0x6BAC9F4</ip>
</frame>
<frame>
<ip>0x451C7EA</ip>
<obj>/lib/i386-linux-gnu/libc-2.13.so</obj>
<fn>getpwuid_r@@GLIBC_2.1.2</fn>
<dir>/build/buildd/eglibc-2.13/pwd/../nss</dir>
<file>getXXbyYY_r.c</file>
<line>256</line>
</frame>
<frame>
<ip>0x85A34E4</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>sm_performSaveYourself(QSessionManagerPrivate*)</fn>
</frame>
<frame>
<ip>0x85A3F56</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>sm_saveYourselfCallback(_SmcConn*, void*, int, int, int, int)</fn>
</frame>
<frame>
<ip>0x4047727</ip>
<obj>/usr/lib/i386-linux-gnu/libSM.so.6.0.1</obj>
<fn>_SmcProcessMessage</fn>
</frame>
<frame>
<ip>0x405D1B5</ip>
<obj>/usr/lib/i386-linux-gnu/libICE.so.6.3.0</obj>
<fn>IceProcessMessages</fn>
</frame>
<frame>
<ip>0x858FE67</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QSmSocketReceiver::socketActivated(int)</fn>
</frame>
<frame>
<ip>0x8D3A9C1</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QMetaObject::activate(QObject*, QMetaObject const*, int, void**)</fn>
</frame>
</stack>
</error>
<error>
<unique>0x118</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>166 (56 direct, 110 indirect) bytes in 1 blocks are definitely lost in loss record 201 of 270</text>
<leakedbytes>166</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402641D</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>operator new(unsigned int)</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>255</line>
</frame>
<frame>
<ip>0x8D0FC45</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibraryPrivate::findOrCreate(QString const&amp;, QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8D1023F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::setFileNameAndVersion(QString const&amp;, QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8D102A4</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLibrary::QLibrary(QString const&amp;, QString const&amp;, QObject*)</fn>
</frame>
<frame>
<ip>0x8C8FA56</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>qt_initIcu(QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8C4B0CF</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLocalePrivate::updateSystemPrivate()</fn>
</frame>
<frame>
<ip>0x8C4B3C6</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>systemPrivate()</fn>
</frame>
<frame>
<ip>0x8C4B40C</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>defaultPrivate()</fn>
</frame>
<frame>
<ip>0x8C4B55F</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QLocale::QLocale()</fn>
</frame>
<frame>
<ip>0x8CCF6F3</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QResourceFileEngine::QResourceFileEngine(QString const&amp;)</fn>
</frame>
<frame>
<ip>0x8CF87DC</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>_q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry&amp;, QFileSystemMetaData&amp;, QAbstractFileEngine*&amp;, bool)</fn>
</frame>
<frame>
<ip>0x8CF8947</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QFileSystemEngine::resolveEntryAndCreateLegacyEngine(QFileSystemEntry&amp;, QFileSystemMetaData&amp;)</fn>
</frame>
</stack>
</error>
<error>
<unique>0x11d</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>216 bytes in 1 blocks are definitely lost in loss record 206 of 270</text>
<leakedbytes>216</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4026864</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>malloc</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>236</line>
</frame>
<frame>
<ip>0x4193FB2</ip>
<obj>/usr/lib/i386-linux-gnu/libX11.so.6.3.0</obj>
<fn>_XimOpenIM</fn>
</frame>
<frame>
<ip>0x4193BCF</ip>
<obj>/usr/lib/i386-linux-gnu/libX11.so.6.3.0</obj>
<fn>_XimRegisterIMInstantiateCallback</fn>
</frame>
<frame>
<ip>0x41789A7</ip>
<obj>/usr/lib/i386-linux-gnu/libX11.so.6.3.0</obj>
<fn>XRegisterIMInstantiateCallback</fn>
</frame>
<frame>
<ip>0x89FB291</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QXIMInputContext::QXIMInputContext()</fn>
</frame>
<frame>
<ip>0x89F9450</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QInputContextFactory::create(QString const&amp;, QObject*)</fn>
</frame>
<frame>
<ip>0x85361C7</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QApplication::inputContext() const</fn>
</frame>
<frame>
<ip>0x85662A7</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QWidgetPrivate::inputContext() const</fn>
</frame>
<frame>
<ip>0x8571D7C</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QWidget::setAttribute(Qt::WidgetAttribute, bool)</fn>
</frame>
<frame>
<ip>0x8A54527</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QGraphicsViewPrivate::updateInputMethodSensitivity()</fn>
</frame>
<frame>
<ip>0x8A55E1A</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QGraphicsView::setScene(QGraphicsScene*)</fn>
</frame>
<frame>
<ip>0x805273E</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QDeclarativeViewPrivate::init()</fn>
</frame>
</stack>
</error>
<error>
<unique>0x126</unique>
<tid>1</tid>
<kind>Leak_PossiblyLost</kind>
<xwhat>
<text>360 bytes in 3 blocks are possibly lost in loss record 215 of 270</text>
<leakedbytes>360</leakedbytes>
<leakedblocks>3</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402517B</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>memalign</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>581</line>
</frame>
<frame>
<ip>0x40251D8</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>posix_memalign</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>709</line>
</frame>
<frame>
<ip>0x42BE546</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
</frame>
<frame>
<ip>0x42BFA4C</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_slice_alloc</fn>
</frame>
<frame>
<ip>0x42C06DD</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_slist_prepend</fn>
</frame>
<frame>
<ip>0x42C368E</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_strsplit</fn>
</frame>
<frame>
<ip>0x42D9393</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_get_language_names</fn>
</frame>
<frame>
<ip>0x42D98E6</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
</frame>
<frame>
<ip>0x42CB919</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_thread_init_glib</fn>
</frame>
<frame>
<ip>0x4254506</ip>
<obj>/usr/lib/i386-linux-gnu/libgthread-2.0.so.0.2800.6</obj>
<fn>g_thread_init</fn>
</frame>
<frame>
<ip>0x8D4D458</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*)</fn>
</frame>
<frame>
<ip>0x85C7CA5</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QGuiEventDispatcherGlibPrivate::QGuiEventDispatcherGlibPrivate()</fn>
</frame>
</stack>
</error>
<error>
<unique>0x128</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>396 (256 direct, 140 indirect) bytes in 2 blocks are definitely lost in loss record 217 of 270</text>
<leakedbytes>396</leakedbytes>
<leakedblocks>2</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4026864</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>malloc</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>236</line>
</frame>
<frame>
<ip>0x4086087</ip>
<obj>/usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4</obj>
</frame>
<frame>
<ip>0x4086F7C</ip>
<obj>/usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4</obj>
</frame>
<frame>
<ip>0x4087073</ip>
<obj>/usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4</obj>
</frame>
<frame>
<ip>0x408C6EB</ip>
<obj>/usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4</obj>
</frame>
<frame>
<ip>0x4607790</ip>
<obj>/lib/i386-linux-gnu/libexpat.so.1.5.2</obj>
</frame>
<frame>
<ip>0x4608670</ip>
<obj>/lib/i386-linux-gnu/libexpat.so.1.5.2</obj>
</frame>
<frame>
<ip>0x4608F92</ip>
<obj>/lib/i386-linux-gnu/libexpat.so.1.5.2</obj>
</frame>
<frame>
<ip>0x460A7D9</ip>
<obj>/lib/i386-linux-gnu/libexpat.so.1.5.2</obj>
</frame>
<frame>
<ip>0x460C5F2</ip>
<obj>/lib/i386-linux-gnu/libexpat.so.1.5.2</obj>
<fn>XML_ParseBuffer</fn>
</frame>
<frame>
<ip>0x408B2B2</ip>
<obj>/usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4</obj>
<fn>FcConfigParseAndLoad</fn>
</frame>
<frame>
<ip>0x408B60B</ip>
<obj>/usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4</obj>
<fn>FcConfigParseAndLoad</fn>
</frame>
</stack>
</error>
<error>
<unique>0x144</unique>
<tid>1</tid>
<kind>Leak_PossiblyLost</kind>
<xwhat>
<text>1,240 bytes in 5 blocks are possibly lost in loss record 245 of 270</text>
<leakedbytes>1240</leakedbytes>
<leakedblocks>5</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x402517B</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>memalign</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>581</line>
</frame>
<frame>
<ip>0x40251D8</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so</obj>
<fn>posix_memalign</fn>
<dir>/build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc</dir>
<file>vg_replace_malloc.c</file>
<line>709</line>
</frame>
<frame>
<ip>0x42BE546</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
</frame>
<frame>
<ip>0x42BFA4C</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_slice_alloc</fn>
</frame>
<frame>
<ip>0x42729D8</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_array_sized_new</fn>
</frame>
<frame>
<ip>0x4272AB2</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_array_new</fn>
</frame>
<frame>
<ip>0x42CB7FE</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_static_private_set</fn>
</frame>
<frame>
<ip>0x4282D0E</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_get_filename_charsets</fn>
</frame>
<frame>
<ip>0x4282D9C</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
</frame>
<frame>
<ip>0x42CB909</ip>
<obj>/lib/i386-linux-gnu/libglib-2.0.so.0.2800.6</obj>
<fn>g_thread_init_glib</fn>
</frame>
<frame>
<ip>0x4254506</ip>
<obj>/usr/lib/i386-linux-gnu/libgthread-2.0.so.0.2800.6</obj>
<fn>g_thread_init</fn>
</frame>
<frame>
<ip>0x8D4D458</ip>
<obj>/home/chris/untitled/untitled</obj>
<fn>QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*)</fn>
</frame>
</stack>
</error>
<errorcounts>
</errorcounts>
<suppcounts>
<pair>
<count>80</count>
<name>U1004-ARM-_dl_relocate_object</name>
</pair>
</suppcounts>
</valgrindoutput>

View File

@@ -1,16 +1,9 @@
TEMPLATE = subdirs TEMPLATE = subdirs
parsertests.file = parsertests.pro
# avoid race conditions when compiling shadowbuild and having more than one compile job # avoid race conditions when compiling shadowbuild and having more than one compile job
modeldemo.depends = parsertests
modeldemo.file = modeldemo.pro modeldemo.file = modeldemo.pro
testapps.depends = modeldemo
testapps.depends = modeldemo parsertests SUBDIRS += modeldemo testapps
testrunner.file = testrunner.pro
testrunner.depends = testapps
SUBDIRS += parsertests modeldemo testapps testrunner

View File

@@ -4,8 +4,6 @@ Project {
name: "Memcheck autotests" name: "Memcheck autotests"
references: [ references: [
"testapps/testapps.qbs", "testapps/testapps.qbs",
"modeldemo.qbs", "modeldemo.qbs"
"parsertests.qbs",
"testrunner.qbs"
] ]
} }

View File

@@ -1,14 +0,0 @@
QTC_LIB_DEPENDS += utils ssh
QTC_PLUGIN_DEPENDS += debugger projectexplorer
include(../../qttest.pri)
include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri)
TARGET = tst_parsertests
QT += network
DEFINES += "PARSERTESTS_DATA_DIR=\\\"$$_PRO_FILE_PWD_/data\\\""
DEFINES += "VALGRIND_FAKE_PATH=\\\"$$IDE_BUILD_TREE/src/tools/valgrindfake/valgrind-fake\\\""
SOURCES += parsertests.cpp
HEADERS += parsertests.h

View File

@@ -1,13 +0,0 @@
import qbs
import "../valgrindautotest.qbs" as ValgrindAutotest
ValgrindAutotest {
name: "Memcheck parser autotest"
Depends { name: "valgrind-fake" }
Depends { name: "Qt.network" }
files: ["parsertests.h", "parsertests.cpp"]
cpp.defines: base.concat([
'PARSERTESTS_DATA_DIR="' + path + '/data"',
'VALGRIND_FAKE_PATH="' + project.buildDirectory + '/' + qtc.ide_bin_path + '/valgrind-fake"'
])
}

View File

@@ -1,12 +0,0 @@
QTC_LIB_DEPENDS += utils ssh
QTC_PLUGIN_DEPENDS += debugger projectexplorer
include(../../qttest.pri)
include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri)
TARGET = tst_testrunner
DEFINES += "TESTRUNNER_SRC_DIR=\\\"$$_PRO_FILE_PWD_/testapps\\\""
DEFINES += "TESTRUNNER_APP_DIR=\\\"$(PWD)/testapps\\\""
SOURCES += testrunner.cpp
HEADERS += testrunner.h

View File

@@ -1,24 +0,0 @@
import qbs
import "../valgrindautotest.qbs" as ValgrindAutotest
ValgrindAutotest {
name: "Memcheck test runner"
Depends { name: "Memcheck free1 autotest" }
Depends { name: "Memcheck free2 autotest" }
Depends { name: "Memcheck invalidjump autotest" }
Depends { name: "Memcheck leak1 autotest" }
Depends { name: "Memcheck leak2 autotest" }
Depends { name: "Memcheck leak3 autotest" }
Depends { name: "Memcheck leak4 autotest" }
Depends { name: "Memcheck overlap autotest" }
Depends { name: "Memcheck syscall autotest" }
Depends { name: "Memcheck uninit1 autotest" }
Depends { name: "Memcheck uninit2 autotest" }
Depends { name: "Memcheck uninit3 autotest" }
files: ["testrunner.h", "testrunner.cpp"]
destinationDirectory: qtc.ide_bin_path
cpp.defines: base.concat([
'TESTRUNNER_SRC_DIR="' + path + '/testapps"',
'TESTRUNNER_APP_DIR="' + project.buildDirectory + '/' + destinationDirectory + '/testapps"'
])
}