forked from qt-creator/qt-creator
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
This commit is contained in:
102
dist/changes-1.1.0
vendored
102
dist/changes-1.1.0
vendored
@@ -1,81 +1,79 @@
|
|||||||
The QtCreator 1.1 release contains bug fixes and new features.
|
The QtCreator 1.1 release contains bug fixes and new features.
|
||||||
|
|
||||||
A more detailed list of changes follows below. If you want to know
|
A more detailed list of changes follows below. If you want to know the exact
|
||||||
the exact and complete list of changes, you can check out the QtCreator
|
and complete list of changes, you can check out the QtCreator sources from the
|
||||||
sources from the public git repository and check the logs, e.g.
|
public git repository and check the logs, e.g.
|
||||||
|
|
||||||
git clone git://labs.trolltech.com/qt-creator
|
git clone git://labs.trolltech.com/qt-creator
|
||||||
git log --pretty=oneline origin/1.0.0..origin/master
|
git log --pretty=oneline v1.0.0..v1.1.0
|
||||||
|
|
||||||
The release introduces source and binary incompatible changes to the plugin API,
|
This release introduces source and binary incompatible changes to the plugin
|
||||||
so if you created your own custom plugins these need to be adapted.
|
API, so if you created your own custom plugins these need to be adapted.
|
||||||
|
|
||||||
General
|
|
||||||
* Completely reworked editor split mechanism.
|
|
||||||
* Supports cmake project
|
|
||||||
* Support generic Makefile based projects
|
|
||||||
|
|
||||||
Editing
|
Editing
|
||||||
* Added support for JavaScript.
|
* Completely reworked editor split mechanism
|
||||||
* Added syntax highlighting and code completion for qdoc and doxygen tags.
|
* Added support for JavaScript
|
||||||
* Improved function argument hint.
|
* Added syntax highlighting and code completion for qdoc and doxygen tags
|
||||||
* More checkpoints in editor history.
|
* Improved function argument hint
|
||||||
* Ctrl-click for jumping to a symbol definition.
|
* Added more checkpoints in editor history
|
||||||
* Improved open documents view (sorted, single-click, close buttons).
|
* Added Ctrl-click for jumping to a symbol definition
|
||||||
* Copying text from the context help browser and output windows didn't work.
|
* Improved open documents view (sorted, single-click, close buttons)
|
||||||
|
* Fixed copying text from the context help browser and output windows
|
||||||
|
* Improved FakeVim mode
|
||||||
|
* Improved C++ parsing and inline error indicators
|
||||||
|
|
||||||
Building and Running
|
Building and Running
|
||||||
* Experimental support for generic Makefile based projects.
|
* Added experimental support for generic Makefile based projects
|
||||||
* Improved .pro file parsing, handling scopes and $$system directive.
|
* Improved .pro file parsing, handling scopes and $$system directive
|
||||||
* Support subdir.file in .pro files.
|
* Added support for subdir.file in .pro files
|
||||||
* Option to start application in external terminal.
|
* Added an option to start the application in an external terminal
|
||||||
|
* Improved CMake support
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
* Possibility to attach debugger to core files.
|
* Made it possible to attach debugger to core files
|
||||||
* Changed approach to dumper loading: Build once per used Qt version,
|
* Changed approach to dumper loading: Build once per used Qt version,
|
||||||
no dumper buildstep anymore.
|
no dumper buildstep anymore
|
||||||
* New dumper for std::set. Improved QString, QVariant, std::wstring
|
* Added a dumper for std::set and improved dumpers for QString, QVariant,
|
||||||
* Make strategy to load shared objects configurable (auto-solib-add).
|
std::wstring
|
||||||
* Increase number of shown stack frames on request instead of loading them all.
|
* Made strategy to load shared objects configurable (auto-solib-add)
|
||||||
* Improved interaction in the Locals&Watchers view.
|
* The number of shown stack frames is now increased on request instead of
|
||||||
|
loading them all
|
||||||
|
* Improved interaction in the Locals & Watchers view
|
||||||
|
|
||||||
Wizards
|
Wizards
|
||||||
* It is now possible to choose file suffixes in the options dialog.
|
* It is now possible to choose default file suffixes in the options dialog
|
||||||
* Code of language change event is now generated correctly (added call
|
* Fixed the code that was generated for handling a language change event
|
||||||
to base class).
|
(added call to base class)
|
||||||
* Generated header guards now adapt to file extension.
|
* Generated header guards now adapt to file extension
|
||||||
|
|
||||||
Designer
|
Designer
|
||||||
* Added signal/slot editor.
|
* Added signal/slot editor
|
||||||
* Fixed "Goto slot" (formatting/multiple inheritance).
|
* Fixed "Goto slot" (formatting/multiple inheritance)
|
||||||
* Context help for form editor widgets.
|
* Context help for form editor widgets
|
||||||
|
|
||||||
Version control plugins
|
Version control plugins
|
||||||
* Fixed handling of colored git output.
|
* Fixed handling of colored git output
|
||||||
* Made svn 1.6 work.
|
* Added syntax highlighting to the git submit editor
|
||||||
* Added syntax highlighting to the git submit editor.
|
* Made git submit editor remove comment lines
|
||||||
* Made git submit editor remove comment lines.
|
* Made Subversion 1.6 work
|
||||||
* Added configuration options for submit editors (user fields, word
|
* Added configuration options for submit editors (user fields, word
|
||||||
wrapping).
|
wrapping)
|
||||||
|
|
||||||
|
|
||||||
Platform Specific
|
Platform Specific
|
||||||
|
|
||||||
Mac
|
Mac
|
||||||
* Don't override systems Hide action.
|
* The system's Hide action is no longer overridden
|
||||||
* Option to set DYLD_IMAGE_SUFFIX=_debug when running applications.
|
* Added option to set DYLD_IMAGE_SUFFIX=_debug when running applications
|
||||||
* Open in Finder action in project tree.
|
* Added Open in Finder action in project tree
|
||||||
|
|
||||||
Linux
|
Linux
|
||||||
* Don't crash because of incompatible libQt3Support:
|
* Fixed crash because of incompatible libQt3Support, by providing a wrapper
|
||||||
Provide a wrapper script and ship libQt3Support.
|
script and shipping libQt3Support.
|
||||||
(Fixes crashes e.g. in file dialogs on openSUSE 11.1)
|
(fixes crashes e.g. in file dialogs on openSUSE 11.1)
|
||||||
|
|
||||||
|
|
||||||
Lots of improvements to
|
|
||||||
* FakeVim mode
|
|
||||||
* CMake support
|
|
||||||
* C++ parsing and inline error indicators
|
|
||||||
* Everything :-)
|
|
||||||
|
|
||||||
Additional credits go to:
|
Additional credits go to:
|
||||||
* Martin Aumueller <aumuell@reserv.at> (FakeVim improvements)
|
* Martin Aumueller <aumuell@reserv.at> (FakeVim improvements)
|
||||||
* Kris Wong (various patches)
|
* Kris Wong (various patches)
|
||||||
|
* Mathias Gumz (fixed permission checks on network NTFS drives)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
IDE_BUILD_TREE=../../..
|
IDE_BUILD_TREE = $$OUT_PWD/../../..
|
||||||
include(../../../qtcreator.pri)
|
include(../../../qtcreator.pri)
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
@@ -110,8 +110,9 @@ QProcess *CMakeManager::createXmlFile(const QStringList &arguments, const QStrin
|
|||||||
QString buildDirectoryPath = buildDirectory.absolutePath();
|
QString buildDirectoryPath = buildDirectory.absolutePath();
|
||||||
qDebug()<<"Creating cbp file in"<<buildDirectoryPath;
|
qDebug()<<"Creating cbp file in"<<buildDirectoryPath;
|
||||||
buildDirectory.mkpath(buildDirectoryPath);
|
buildDirectory.mkpath(buildDirectoryPath);
|
||||||
QProcess * cmake = new QProcess;
|
QProcess *cmake = new QProcess;
|
||||||
cmake->setWorkingDirectory(buildDirectoryPath);
|
cmake->setWorkingDirectory(buildDirectoryPath);
|
||||||
|
cmake->setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString generator = "-GCodeBlocks - MinGW Makefiles";
|
QString generator = "-GCodeBlocks - MinGW Makefiles";
|
||||||
|
0
src/plugins/coreplugin/images/qtcreator_logo_256.png
Executable file → Normal file
0
src/plugins/coreplugin/images/qtcreator_logo_256.png
Executable file → Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
0
src/plugins/coreplugin/images/qtcreator_logo_512.png
Executable file → Normal file
0
src/plugins/coreplugin/images/qtcreator_logo_512.png
Executable file → Normal file
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@@ -100,7 +100,7 @@ WelcomeModePrivate::WelcomeModePrivate() :
|
|||||||
|
|
||||||
#if defined(QT_NO_WEBKIT)
|
#if defined(QT_NO_WEBKIT)
|
||||||
|
|
||||||
const char LABEL[] = Q_TRANSLATE_NOOP("Core::Internal::WelcomeMode",
|
const char LABEL[] = QT_TRANSLATE_NOOP("Core::Internal::WelcomeMode",
|
||||||
"<center><table><tr><td><img src=\":/core/html/images/product_logo.png\"/></td><td width=300>"
|
"<center><table><tr><td><img src=\":/core/html/images/product_logo.png\"/></td><td width=300>"
|
||||||
"<h2><br/><br/>Welcome</h2><p> Qt Creator is an intuitive, modern cross platform IDE that enables "
|
"<h2><br/><br/>Welcome</h2><p> Qt Creator is an intuitive, modern cross platform IDE that enables "
|
||||||
"developers to create graphically appealing applications for desktop, "
|
"developers to create graphically appealing applications for desktop, "
|
||||||
|
@@ -604,6 +604,13 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
|
|||||||
|
|
||||||
QTextCursor tc = cursor;
|
QTextCursor tc = cursor;
|
||||||
|
|
||||||
|
// Make sure we're not at the start of a word
|
||||||
|
{
|
||||||
|
const QChar c = characterAt(tc.position());
|
||||||
|
if (c.isLetter() || c == QLatin1Char('_'))
|
||||||
|
tc.movePosition(QTextCursor::Right);
|
||||||
|
}
|
||||||
|
|
||||||
static TokenUnderCursor tokenUnderCursor;
|
static TokenUnderCursor tokenUnderCursor;
|
||||||
|
|
||||||
QTextBlock block;
|
QTextBlock block;
|
||||||
|
@@ -27,6 +27,7 @@ INCLUDEPATH*=$$PWD
|
|||||||
CDB_LIBPATH=$$CDB_PATH/lib/$$CDB_PLATFORM
|
CDB_LIBPATH=$$CDB_PATH/lib/$$CDB_PLATFORM
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
$$PWD/cdbcom.h \
|
||||||
$$PWD/cdbdebugengine.h \
|
$$PWD/cdbdebugengine.h \
|
||||||
$$PWD/cdbdebugengine_p.h \
|
$$PWD/cdbdebugengine_p.h \
|
||||||
$$PWD/cdbdebugeventcallback.h \
|
$$PWD/cdbdebugeventcallback.h \
|
||||||
|
@@ -42,8 +42,8 @@ namespace Internal {
|
|||||||
|
|
||||||
typedef QList<DisassemblerLine> DisassemblerLineList;
|
typedef QList<DisassemblerLine> DisassemblerLineList;
|
||||||
|
|
||||||
bool getRegisters(IDebugControl4 *ctl,
|
bool getRegisters(CIDebugControl *ctl,
|
||||||
IDebugRegisters2 *ireg,
|
CIDebugRegisters *ireg,
|
||||||
QList<Register> *registers,
|
QList<Register> *registers,
|
||||||
QString *errorMessage, int base)
|
QString *errorMessage, int base)
|
||||||
{
|
{
|
||||||
@@ -194,8 +194,8 @@ void DisassemblerOutputParser::parse(const QStringList &l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dissassemble(IDebugClient5 *client,
|
bool dissassemble(CIDebugClient *client,
|
||||||
IDebugControl4 *ctl,
|
CIDebugControl *ctl,
|
||||||
ULONG64 offset,
|
ULONG64 offset,
|
||||||
unsigned long beforeLines,
|
unsigned long beforeLines,
|
||||||
unsigned long afterLines,
|
unsigned long afterLines,
|
||||||
|
@@ -33,8 +33,7 @@
|
|||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -44,14 +43,14 @@ class DisassemblerLine;
|
|||||||
// Utilities related to assembler code.
|
// Utilities related to assembler code.
|
||||||
class Register;
|
class Register;
|
||||||
|
|
||||||
bool getRegisters(IDebugControl4 *ctl,
|
bool getRegisters(CIDebugControl *ctl,
|
||||||
IDebugRegisters2 *ireg,
|
CIDebugRegisters *ireg,
|
||||||
QList<Register> *registers,
|
QList<Register> *registers,
|
||||||
QString *errorMessage,
|
QString *errorMessage,
|
||||||
int base = 10 /* 16 for hex, etc */);
|
int base = 10 /* 16 for hex, etc */);
|
||||||
|
|
||||||
bool dissassemble(IDebugClient5 *client,
|
bool dissassemble(CIDebugClient *client,
|
||||||
IDebugControl4 *ctl,
|
CIDebugControl *ctl,
|
||||||
ULONG64 offset,
|
ULONG64 offset,
|
||||||
unsigned long beforeLines,
|
unsigned long beforeLines,
|
||||||
unsigned long afterLines,
|
unsigned long afterLines,
|
||||||
|
@@ -131,7 +131,7 @@ QString CDBBreakPoint::expression() const
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBBreakPoint::apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const
|
bool CDBBreakPoint::apply(CIDebugBreakpoint *ibp, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
const QString expr = expression();
|
const QString expr = expression();
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
@@ -148,7 +148,7 @@ bool CDBBreakPoint::apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBBreakPoint::add(IDebugControl4* debugControl, QString *errorMessage) const
|
bool CDBBreakPoint::add(CIDebugControl* debugControl, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
IDebugBreakpoint2* ibp = 0;
|
IDebugBreakpoint2* ibp = 0;
|
||||||
const HRESULT hr = debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &ibp);
|
const HRESULT hr = debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &ibp);
|
||||||
@@ -176,7 +176,7 @@ QString CDBBreakPoint::canonicalSourceFile(const QString &f)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBBreakPoint::retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage)
|
bool CDBBreakPoint::retrieve(CIDebugBreakpoint *ibp, QString *errorMessage)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
WCHAR wszBuf[MAX_PATH];
|
WCHAR wszBuf[MAX_PATH];
|
||||||
@@ -245,7 +245,7 @@ bool CDBBreakPoint::parseExpression(const QString &expr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBBreakPoint::getBreakPointCount(IDebugControl4* debugControl, ULONG *count, QString *errorMessage /* = 0*/)
|
bool CDBBreakPoint::getBreakPointCount(CIDebugControl* debugControl, ULONG *count, QString *errorMessage /* = 0*/)
|
||||||
{
|
{
|
||||||
const HRESULT hr = debugControl->GetNumberBreakpoints(count);
|
const HRESULT hr = debugControl->GetNumberBreakpoints(count);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@@ -257,7 +257,7 @@ bool CDBBreakPoint::getBreakPointCount(IDebugControl4* debugControl, ULONG *coun
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBBreakPoint::getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage)
|
bool CDBBreakPoint::getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage)
|
||||||
{
|
{
|
||||||
ULONG count = 0;
|
ULONG count = 0;
|
||||||
bps->clear();
|
bps->clear();
|
||||||
|
@@ -30,8 +30,7 @@
|
|||||||
#ifndef CDBBREAKPOINTS_H
|
#ifndef CDBBREAKPOINTS_H
|
||||||
#define CDBBREAKPOINTS_H
|
#define CDBBREAKPOINTS_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
@@ -64,16 +63,16 @@ struct CDBBreakPoint
|
|||||||
// Apply parameters
|
// Apply parameters
|
||||||
bool apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const;
|
bool apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const;
|
||||||
// Convenience to add to a IDebugControl4
|
// Convenience to add to a IDebugControl4
|
||||||
bool add(IDebugControl4* debugControl, QString *errorMessage) const;
|
bool add(CIDebugControl* debugControl, QString *errorMessage) const;
|
||||||
|
|
||||||
// Retrieve/parse breakpoints from the interfaces
|
// Retrieve/parse breakpoints from the interfaces
|
||||||
bool retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage);
|
bool retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage);
|
||||||
bool parseExpression(const QString &expr);
|
bool parseExpression(const QString &expr);
|
||||||
// Retrieve all breakpoints from the engine
|
// Retrieve all breakpoints from the engine
|
||||||
static bool getBreakPointCount(IDebugControl4* debugControl, ULONG *count, QString *errorMessage = 0);
|
static bool getBreakPointCount(CIDebugControl* debugControl, ULONG *count, QString *errorMessage = 0);
|
||||||
static bool getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
|
static bool getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
|
||||||
// Synchronize (halted) engine with BreakHandler.
|
// Synchronize (halted) engine with BreakHandler.
|
||||||
static bool synchronizeBreakPoints(IDebugControl4* ctl, IDebugSymbols3 *syms,
|
static bool synchronizeBreakPoints(CIDebugControl* ctl, CIDebugSymbols *syms,
|
||||||
BreakHandler *bh, QString *errorMessage);
|
BreakHandler *bh, QString *errorMessage);
|
||||||
|
|
||||||
// Return a 'canonical' file (using '/' and capitalized drive letter)
|
// Return a 'canonical' file (using '/' and capitalized drive letter)
|
||||||
|
46
src/plugins/debugger/cdb/cdbcom.h
Normal file
46
src/plugins/debugger/cdb/cdbcom.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at qt-sales@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CDBCOM_H
|
||||||
|
#define CDBCOM_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <inc/dbgeng.h>
|
||||||
|
|
||||||
|
// typedef out the version numbers
|
||||||
|
typedef IDebugClient5 CIDebugClient;
|
||||||
|
typedef IDebugControl4 CIDebugControl;
|
||||||
|
typedef IDebugSystemObjects4 CIDebugSystemObjects;
|
||||||
|
typedef IDebugSymbols3 CIDebugSymbols;
|
||||||
|
typedef IDebugRegisters2 CIDebugRegisters;
|
||||||
|
typedef IDebugDataSpaces4 CIDebugDataSpaces;
|
||||||
|
|
||||||
|
typedef IDebugSymbolGroup2 CIDebugSymbolGroup;
|
||||||
|
typedef IDebugBreakpoint2 CIDebugBreakpoint;
|
||||||
|
#endif // CDBCOM_H
|
@@ -125,25 +125,74 @@ static inline QString msgLibLoadFailed(const QString &lib, const QString &why)
|
|||||||
|
|
||||||
// ----- Engine helpers
|
// ----- Engine helpers
|
||||||
|
|
||||||
static inline ULONG getInterruptTimeOutSecs(IDebugControl4 *ctl)
|
static inline ULONG getInterruptTimeOutSecs(CIDebugControl *ctl)
|
||||||
{
|
{
|
||||||
ULONG rc = 0;
|
ULONG rc = 0;
|
||||||
ctl->GetInterruptTimeout(&rc);
|
ctl->GetInterruptTimeout(&rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool getExecutionStatus(IDebugControl4 *ctl,
|
bool getExecutionStatus(CIDebugControl *ctl,
|
||||||
ULONG *executionStatus,
|
ULONG *executionStatus,
|
||||||
QString *errorMessage)
|
QString *errorMessage /* = 0 */)
|
||||||
{
|
{
|
||||||
const HRESULT hr = ctl->GetExecutionStatus(executionStatus);
|
const HRESULT hr = ctl->GetExecutionStatus(executionStatus);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = msgComFailed("GetExecutionStatus", hr);
|
if (errorMessage)
|
||||||
|
*errorMessage = msgComFailed("GetExecutionStatus", hr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *executionStatusString(ULONG executionStatus)
|
||||||
|
{
|
||||||
|
switch (executionStatus) {
|
||||||
|
case DEBUG_STATUS_NO_CHANGE:
|
||||||
|
return "DEBUG_STATUS_NO_CHANGE";
|
||||||
|
case DEBUG_STATUS_GO:
|
||||||
|
return "DEBUG_STATUS_GO";
|
||||||
|
case DEBUG_STATUS_GO_HANDLED:
|
||||||
|
return "DEBUG_STATUS_GO_HANDLED";
|
||||||
|
case DEBUG_STATUS_GO_NOT_HANDLED:
|
||||||
|
return "DEBUG_STATUS_GO_NOT_HANDLED";
|
||||||
|
case DEBUG_STATUS_STEP_OVER:
|
||||||
|
return "DEBUG_STATUS_STEP_OVER";
|
||||||
|
case DEBUG_STATUS_STEP_INTO:
|
||||||
|
return "DEBUG_STATUS_STEP_INTO";
|
||||||
|
case DEBUG_STATUS_BREAK:
|
||||||
|
return "DEBUG_STATUS_BREAK";
|
||||||
|
case DEBUG_STATUS_NO_DEBUGGEE:
|
||||||
|
return "DEBUG_STATUS_NO_DEBUGGEE";
|
||||||
|
case DEBUG_STATUS_STEP_BRANCH:
|
||||||
|
return "DEBUG_STATUS_STEP_BRANCH";
|
||||||
|
case DEBUG_STATUS_IGNORE_EVENT:
|
||||||
|
return "DEBUG_STATUS_IGNORE_EVENT";
|
||||||
|
case DEBUG_STATUS_RESTART_REQUESTED:
|
||||||
|
return "DEBUG_STATUS_RESTART_REQUESTED";
|
||||||
|
case DEBUG_STATUS_REVERSE_GO:
|
||||||
|
return "DEBUG_STATUS_REVERSE_GO";
|
||||||
|
case DEBUG_STATUS_REVERSE_STEP_BRANCH:
|
||||||
|
return "DEBUG_STATUS_REVERSE_STEP_BRANCH";
|
||||||
|
case DEBUG_STATUS_REVERSE_STEP_OVER:
|
||||||
|
return "DEBUG_STATUS_REVERSE_STEP_OVER";
|
||||||
|
case DEBUG_STATUS_REVERSE_STEP_INTO:
|
||||||
|
return "DEBUG_STATUS_REVERSE_STEP_INTO";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "<Unknown execution status>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug convenience
|
||||||
|
const char *executionStatusString(CIDebugControl *ctl)
|
||||||
|
{
|
||||||
|
ULONG executionStatus;
|
||||||
|
if (getExecutionStatus(ctl, &executionStatus))
|
||||||
|
return executionStatusString(executionStatus);
|
||||||
|
return "<failed>";
|
||||||
|
}
|
||||||
|
|
||||||
// --------- DebuggerEngineLibrary
|
// --------- DebuggerEngineLibrary
|
||||||
DebuggerEngineLibrary::DebuggerEngineLibrary() :
|
DebuggerEngineLibrary::DebuggerEngineLibrary() :
|
||||||
m_debugCreate(0)
|
m_debugCreate(0)
|
||||||
@@ -189,7 +238,7 @@ bool DebuggerEngineLibrary::init(const QString &path, QString *errorMessage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----- SyntaxSetter
|
// ----- SyntaxSetter
|
||||||
SyntaxSetter::SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax) :
|
SyntaxSetter::SyntaxSetter(CIDebugControl *ctl, ULONG desiredSyntax) :
|
||||||
m_desiredSyntax(desiredSyntax),
|
m_desiredSyntax(desiredSyntax),
|
||||||
m_ctl(ctl)
|
m_ctl(ctl)
|
||||||
{
|
{
|
||||||
@@ -385,8 +434,10 @@ void CdbDebugEngine::shutdown()
|
|||||||
exitDebugger();
|
exitDebugger();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::setToolTipExpression(const QPoint & /*pos*/, const QString & /*exp*/)
|
void CdbDebugEngine::setToolTipExpression(const QPoint & pos, const QString & exp)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << '\n' << pos << exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEnginePrivate::clearDisplay()
|
void CdbDebugEnginePrivate::clearDisplay()
|
||||||
@@ -939,7 +990,7 @@ void CdbDebugEngine::executeDebuggerCommand(const QString &command)
|
|||||||
qWarning("%s\n", qPrintable(errorMessage));
|
qWarning("%s\n", qPrintable(errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbDebugEnginePrivate::executeDebuggerCommand(IDebugControl4 *ctrl, const QString &command, QString *errorMessage)
|
bool CdbDebugEnginePrivate::executeDebuggerCommand(CIDebugControl *ctrl, const QString &command, QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
qDebug() << Q_FUNC_INFO << command;
|
qDebug() << Q_FUNC_INFO << command;
|
||||||
@@ -1186,6 +1237,10 @@ void CdbDebugEngine::reloadRegisters()
|
|||||||
|
|
||||||
void CdbDebugEngine::timerEvent(QTimerEvent* te)
|
void CdbDebugEngine::timerEvent(QTimerEvent* te)
|
||||||
{
|
{
|
||||||
|
// Fetch away the debug events and notify if debuggee
|
||||||
|
// stops. Note that IDebugEventCallback does not
|
||||||
|
// cover all cases of a debuggee stopping execution
|
||||||
|
// (such as step over,etc).
|
||||||
if (te->timerId() != m_d->m_watchTimer)
|
if (te->timerId() != m_d->m_watchTimer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1319,8 +1374,7 @@ void CdbDebugEnginePrivate::updateStackTrace()
|
|||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
m_engine->reloadRegisters();
|
m_engine->reloadRegisters();
|
||||||
m_currentStackTrace =
|
m_currentStackTrace =
|
||||||
CdbStackTraceContext::create(m_cif.debugControl, m_cif.debugSystemObjects,
|
CdbStackTraceContext::create(&m_cif, m_currentThreadId, &errorMessage);
|
||||||
m_cif.debugSymbols, m_currentThreadId, &errorMessage);
|
|
||||||
if (!m_currentStackTrace) {
|
if (!m_currentStackTrace) {
|
||||||
qWarning("%s: failed to create trace context: %s", Q_FUNC_INFO, qPrintable(errorMessage));
|
qWarning("%s: failed to create trace context: %s", Q_FUNC_INFO, qPrintable(errorMessage));
|
||||||
return;
|
return;
|
||||||
|
@@ -73,11 +73,11 @@ private:
|
|||||||
class SyntaxSetter {
|
class SyntaxSetter {
|
||||||
Q_DISABLE_COPY(SyntaxSetter)
|
Q_DISABLE_COPY(SyntaxSetter)
|
||||||
public:
|
public:
|
||||||
explicit inline SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax);
|
explicit inline SyntaxSetter(CIDebugControl *ctl, ULONG desiredSyntax);
|
||||||
inline ~SyntaxSetter();
|
inline ~SyntaxSetter();
|
||||||
private:
|
private:
|
||||||
const ULONG m_desiredSyntax;
|
const ULONG m_desiredSyntax;
|
||||||
IDebugControl4 *m_ctl;
|
CIDebugControl *m_ctl;
|
||||||
ULONG m_oldSyntax;
|
ULONG m_oldSyntax;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,12 +85,12 @@ private:
|
|||||||
struct CdbComInterfaces
|
struct CdbComInterfaces
|
||||||
{
|
{
|
||||||
CdbComInterfaces();
|
CdbComInterfaces();
|
||||||
IDebugClient5* debugClient;
|
CIDebugClient* debugClient;
|
||||||
IDebugControl4* debugControl;
|
CIDebugControl* debugControl;
|
||||||
IDebugSystemObjects4* debugSystemObjects;
|
CIDebugSystemObjects* debugSystemObjects;
|
||||||
IDebugSymbols3* debugSymbols;
|
CIDebugSymbols* debugSymbols;
|
||||||
IDebugRegisters2* debugRegisters;
|
CIDebugRegisters* debugRegisters;
|
||||||
IDebugDataSpaces4* debugDataSpaces;
|
CIDebugDataSpaces* debugDataSpaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CdbDebugEnginePrivate
|
struct CdbDebugEnginePrivate
|
||||||
@@ -130,7 +130,7 @@ struct CdbDebugEnginePrivate
|
|||||||
|
|
||||||
bool attemptBreakpointSynchronization(QString *errorMessage);
|
bool attemptBreakpointSynchronization(QString *errorMessage);
|
||||||
|
|
||||||
static bool executeDebuggerCommand(IDebugControl4 *ctrl, const QString &command, QString *errorMessage);
|
static bool executeDebuggerCommand(CIDebugControl *ctrl, const QString &command, QString *errorMessage);
|
||||||
|
|
||||||
const QSharedPointer<CdbOptions> m_options;
|
const QSharedPointer<CdbOptions> m_options;
|
||||||
HANDLE m_hDebuggeeProcess;
|
HANDLE m_hDebuggeeProcess;
|
||||||
@@ -154,6 +154,12 @@ struct CdbDebugEnginePrivate
|
|||||||
Core::Utils::ConsoleProcess m_consoleStubProc;
|
Core::Utils::ConsoleProcess m_consoleStubProc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
|
||||||
|
bool getExecutionStatus(CIDebugControl *ctl, ULONG *executionStatus, QString *errorMessage = 0);
|
||||||
|
const char *executionStatusString(ULONG executionStatus);
|
||||||
|
const char *executionStatusString(CIDebugControl *ctl);
|
||||||
|
|
||||||
// Message
|
// Message
|
||||||
QString msgDebugEngineComResult(HRESULT hr);
|
QString msgDebugEngineComResult(HRESULT hr);
|
||||||
QString msgComFailed(const char *func, HRESULT hr);
|
QString msgComFailed(const char *func, HRESULT hr);
|
||||||
|
@@ -32,8 +32,12 @@
|
|||||||
#include "cdbdebugengine_p.h"
|
#include "cdbdebugengine_p.h"
|
||||||
#include "debuggermanager.h"
|
#include "debuggermanager.h"
|
||||||
#include "breakhandler.h"
|
#include "breakhandler.h"
|
||||||
|
#include "cdbstacktracecontext.h"
|
||||||
|
|
||||||
|
enum { cppExceptionCode = 0xe06d7363 };
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -198,7 +202,7 @@ STDMETHODIMP CdbDebugEventCallbackBase::ChangeSymbolState(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(IDebugClient5 *clnt)
|
IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(CIDebugClient *clnt)
|
||||||
{
|
{
|
||||||
IDebugEventCallbacksWide *rc = 0;
|
IDebugEventCallbacksWide *rc = 0;
|
||||||
if (SUCCEEDED(clnt->GetEventCallbacksWide(&rc)))
|
if (SUCCEEDED(clnt->GetEventCallbacksWide(&rc)))
|
||||||
@@ -231,26 +235,116 @@ STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT2 Bp)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString msgException(const EXCEPTION_RECORD64 *Exception, ULONG FirstChance)
|
// Simple exception formatting
|
||||||
|
void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
|
||||||
{
|
{
|
||||||
return QString::fromLatin1("An exception occurred: Code=0x%1 FirstChance=%2").
|
str.setIntegerBase(16);
|
||||||
arg(QString::number(Exception->ExceptionCode, 16)).
|
str << "\nException at 0x" << e->ExceptionAddress
|
||||||
arg(FirstChance);
|
<< ", code: 0x" << e->ExceptionCode << ": ";
|
||||||
|
switch (e->ExceptionCode) {
|
||||||
|
case cppExceptionCode:
|
||||||
|
str << "C++ exception";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_ACCESS_VIOLATION: {
|
||||||
|
const bool writeOperation = e->ExceptionInformation[0];
|
||||||
|
str << (writeOperation ? "write access violation" : "read access violation");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||||
|
str << "arrary bounds exceeded";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_BREAKPOINT:
|
||||||
|
str << "breakpoint";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||||
|
str << "datatype misalignment";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||||
|
str << "floating point exception";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||||
|
str << "division by zero";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||||
|
str << " floating-point operation cannot be represented exactly as a decimal fraction";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||||
|
str << "invalid floating-point operation";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_OVERFLOW:
|
||||||
|
str << "floating-point overflow";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_STACK_CHECK:
|
||||||
|
str << "floating-point operation stack over/underflow";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_FLT_UNDERFLOW:
|
||||||
|
str << "floating-point UNDERFLOW";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||||
|
str << "invalid instruction";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_IN_PAGE_ERROR:
|
||||||
|
str << "page in error";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||||
|
str << "integer division by zero";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_INT_OVERFLOW:
|
||||||
|
str << "integer overflow";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_INVALID_DISPOSITION:
|
||||||
|
str << "invalid disposition to exception dispatcher";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||||
|
str << "attempt to continue execution after noncontinuable exception";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_PRIV_INSTRUCTION:
|
||||||
|
str << "priviledged instruction";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_SINGLE_STEP:
|
||||||
|
str << "single step";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_STACK_OVERFLOW:
|
||||||
|
str << "stack_overflow";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str << ", flags=0x" << e->ExceptionFlags;
|
||||||
|
if (e->ExceptionFlags == EXCEPTION_NONCONTINUABLE) {
|
||||||
|
str << " (execution cannot be continued)";
|
||||||
|
}
|
||||||
|
str << "\n\n";
|
||||||
|
str.setIntegerBase(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format exception with stacktrace in case of C++ exception
|
||||||
|
void formatException(const EXCEPTION_RECORD64 *e, CdbComInterfaces &cif, QTextStream &str)
|
||||||
|
{
|
||||||
|
formatException(e, str);
|
||||||
|
if (e->ExceptionCode == cppExceptionCode) {
|
||||||
|
QString errorMessage;
|
||||||
|
ULONG currentThreadId = 0;
|
||||||
|
cif.debugSystemObjects->GetCurrentThreadId(¤tThreadId);
|
||||||
|
if (CdbStackTraceContext *stc = CdbStackTraceContext::create(&cif, currentThreadId, &errorMessage)) {
|
||||||
|
str << "at:\n";
|
||||||
|
stc->format(str);
|
||||||
|
str <<'\n';
|
||||||
|
delete stc;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CdbDebugEventCallback::Exception(
|
STDMETHODIMP CdbDebugEventCallback::Exception(
|
||||||
THIS_
|
THIS_
|
||||||
__in PEXCEPTION_RECORD64 Exception,
|
__in PEXCEPTION_RECORD64 Exception,
|
||||||
__in ULONG FirstChance
|
__in ULONG /* FirstChance */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Q_UNUSED(Exception)
|
QString msg;
|
||||||
if (debugCDB)
|
{
|
||||||
qDebug() << Q_FUNC_INFO << msgException(Exception, FirstChance);
|
QTextStream str(&msg);
|
||||||
|
formatException(Exception, m_pEngine->m_d->m_cif, str);
|
||||||
// First chance are harmless
|
}
|
||||||
if (!FirstChance)
|
m_pEngine->m_d->m_debuggerManagerAccess->showApplicationOutput(msg);
|
||||||
qWarning("%s", qPrintable(msgException(Exception, FirstChance)));
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,7 +489,7 @@ STDMETHODIMP IgnoreDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------- EventCallbackRedirector
|
// --------- EventCallbackRedirector
|
||||||
EventCallbackRedirector::EventCallbackRedirector(IDebugClient5 *client, IDebugEventCallbacksWide *cb) :
|
EventCallbackRedirector::EventCallbackRedirector(CIDebugClient *client, IDebugEventCallbacksWide *cb) :
|
||||||
m_client(client),
|
m_client(client),
|
||||||
m_oldCb(CdbDebugEventCallbackBase::getEventCallback(client))
|
m_oldCb(CdbDebugEventCallbackBase::getEventCallback(client))
|
||||||
{
|
{
|
||||||
|
@@ -30,8 +30,8 @@
|
|||||||
#ifndef DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
#ifndef DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||||
#define DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
#define DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
@@ -151,7 +151,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
static IDebugEventCallbacksWide *getEventCallback(IDebugClient5 *clnt);
|
static IDebugEventCallbacksWide *getEventCallback(CIDebugClient *clnt);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CdbDebugEventCallback : public CdbDebugEventCallbackBase
|
class CdbDebugEventCallback : public CdbDebugEventCallbackBase
|
||||||
@@ -252,10 +252,10 @@ public:
|
|||||||
class EventCallbackRedirector {
|
class EventCallbackRedirector {
|
||||||
Q_DISABLE_COPY(EventCallbackRedirector)
|
Q_DISABLE_COPY(EventCallbackRedirector)
|
||||||
public:
|
public:
|
||||||
explicit EventCallbackRedirector(IDebugClient5 *client, IDebugEventCallbacksWide *cb);
|
explicit EventCallbackRedirector(CIDebugClient *client, IDebugEventCallbacksWide *cb);
|
||||||
~EventCallbackRedirector();
|
~EventCallbackRedirector();
|
||||||
private:
|
private:
|
||||||
IDebugClient5 *m_client;
|
CIDebugClient *m_client;
|
||||||
IDebugEventCallbacksWide *m_oldCb;
|
IDebugEventCallbacksWide *m_oldCb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -84,7 +84,7 @@ STDMETHODIMP CdbDebugOutputBase::Output(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDebugOutputCallbacksWide *CdbDebugOutputBase::getOutputCallback(IDebugClient5 *client)
|
IDebugOutputCallbacksWide *CdbDebugOutputBase::getOutputCallback(CIDebugClient *client)
|
||||||
{
|
{
|
||||||
IDebugOutputCallbacksWide *rc;
|
IDebugOutputCallbacksWide *rc;
|
||||||
if (FAILED(client->GetOutputCallbacksWide(&rc)))
|
if (FAILED(client->GetOutputCallbacksWide(&rc)))
|
||||||
@@ -157,7 +157,7 @@ void CdbDebugOutput::output(ULONG mask, const QString &msg)
|
|||||||
|
|
||||||
// Utility class to temporarily redirect output to another handler
|
// Utility class to temporarily redirect output to another handler
|
||||||
// as long as in scope
|
// as long as in scope
|
||||||
OutputRedirector::OutputRedirector(IDebugClient5 *client, IDebugOutputCallbacksWide *newHandler) :
|
OutputRedirector::OutputRedirector(CIDebugClient *client, IDebugOutputCallbacksWide *newHandler) :
|
||||||
m_client(client),
|
m_client(client),
|
||||||
m_oldHandler(CdbDebugOutputBase::getOutputCallback(client))
|
m_oldHandler(CdbDebugOutputBase::getOutputCallback(client))
|
||||||
{
|
{
|
||||||
|
@@ -30,8 +30,7 @@
|
|||||||
#ifndef DEBUGGER_CDBOUTPUT_H
|
#ifndef DEBUGGER_CDBOUTPUT_H
|
||||||
#define DEBUGGER_CDBOUTPUT_H
|
#define DEBUGGER_CDBOUTPUT_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Helpers to retrieve the output callbacks IF
|
// Helpers to retrieve the output callbacks IF
|
||||||
static IDebugOutputCallbacksWide *getOutputCallback(IDebugClient5 *client);
|
static IDebugOutputCallbacksWide *getOutputCallback(CIDebugClient *client);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CdbDebugOutputBase();
|
CdbDebugOutputBase();
|
||||||
@@ -110,10 +109,10 @@ private:
|
|||||||
class OutputRedirector {
|
class OutputRedirector {
|
||||||
Q_DISABLE_COPY(OutputRedirector)
|
Q_DISABLE_COPY(OutputRedirector)
|
||||||
public:
|
public:
|
||||||
explicit OutputRedirector(IDebugClient5 *client, IDebugOutputCallbacksWide *newHandler);
|
explicit OutputRedirector(CIDebugClient *client, IDebugOutputCallbacksWide *newHandler);
|
||||||
~OutputRedirector();
|
~OutputRedirector();
|
||||||
private:
|
private:
|
||||||
IDebugClient5 *m_client;
|
CIDebugClient *m_client;
|
||||||
IDebugOutputCallbacksWide *m_oldHandler;
|
IDebugOutputCallbacksWide *m_oldHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -42,8 +42,8 @@ namespace Internal {
|
|||||||
|
|
||||||
// Alloc memory in debuggee using the ".dvalloc" command as
|
// Alloc memory in debuggee using the ".dvalloc" command as
|
||||||
// there seems to be no API for it.
|
// there seems to be no API for it.
|
||||||
static bool allocDebuggeeMemory(IDebugControl4 *ctl,
|
static bool allocDebuggeeMemory(CIDebugControl *ctl,
|
||||||
IDebugClient5 *client,
|
CIDebugClient *client,
|
||||||
int size, ULONG64 *address, QString *errorMessage)
|
int size, ULONG64 *address, QString *errorMessage)
|
||||||
{
|
{
|
||||||
*address = 0;
|
*address = 0;
|
||||||
@@ -69,9 +69,9 @@ static bool allocDebuggeeMemory(IDebugControl4 *ctl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Alloc an AscII string in debuggee
|
// Alloc an AscII string in debuggee
|
||||||
static bool createDebuggeeAscIIString(IDebugControl4 *ctl,
|
static bool createDebuggeeAscIIString(CIDebugControl *ctl,
|
||||||
IDebugClient5 *client,
|
CIDebugClient *client,
|
||||||
IDebugDataSpaces4 *data,
|
CIDebugDataSpaces *data,
|
||||||
const QString &s,
|
const QString &s,
|
||||||
ULONG64 *address,
|
ULONG64 *address,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
@@ -90,7 +90,7 @@ static bool createDebuggeeAscIIString(IDebugControl4 *ctl,
|
|||||||
|
|
||||||
// Locate 'qstrdup' in the (potentially namespaced) corelib. For some
|
// Locate 'qstrdup' in the (potentially namespaced) corelib. For some
|
||||||
// reason, the symbol is present in QtGui as well without type information.
|
// reason, the symbol is present in QtGui as well without type information.
|
||||||
static inline QString resolveStrdup(IDebugSymbols3 *syms, QString *errorMessage)
|
static inline QString resolveStrdup(CIDebugSymbols *syms, QString *errorMessage)
|
||||||
{
|
{
|
||||||
QStringList matches;
|
QStringList matches;
|
||||||
const QString pattern = QLatin1String("*qstrdup");
|
const QString pattern = QLatin1String("*qstrdup");
|
||||||
@@ -111,10 +111,10 @@ static inline QString resolveStrdup(IDebugSymbols3 *syms, QString *errorMessage)
|
|||||||
// the QtCored4.pdb file to be present as we need "qstrdup"
|
// the QtCored4.pdb file to be present as we need "qstrdup"
|
||||||
// as dummy symbol. This is ok ATM since dumpers only
|
// as dummy symbol. This is ok ATM since dumpers only
|
||||||
// make sense for Qt apps.
|
// make sense for Qt apps.
|
||||||
static bool debuggeeLoadLibrary(IDebugControl4 *ctl,
|
static bool debuggeeLoadLibrary(CIDebugControl *ctl,
|
||||||
IDebugClient5 *client,
|
CIDebugClient *client,
|
||||||
IDebugSymbols3 *syms,
|
CIDebugSymbols *syms,
|
||||||
IDebugDataSpaces4 *data,
|
CIDebugDataSpaces *data,
|
||||||
const QString &moduleName, QString *errorMessage)
|
const QString &moduleName, QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (loadDebug)
|
if (loadDebug)
|
||||||
@@ -179,7 +179,7 @@ bool CdbDumperHelper::moduleLoadHook(const QString &name, bool *ignoreNextBreakP
|
|||||||
// Load once QtCore is there.
|
// Load once QtCore is there.
|
||||||
if (name.contains(QLatin1String("QtCore"))) {
|
if (name.contains(QLatin1String("QtCore"))) {
|
||||||
if (loadDebug)
|
if (loadDebug)
|
||||||
qDebug() << Q_FUNC_INFO << '\n' << name << m_state;
|
qDebug() << Q_FUNC_INFO << '\n' << name << m_state << executionStatusString(m_cif->debugControl);
|
||||||
ok = debuggeeLoadLibrary(m_cif->debugControl, m_cif->debugClient, m_cif->debugSymbols, m_cif->debugDataSpaces,
|
ok = debuggeeLoadLibrary(m_cif->debugControl, m_cif->debugClient, m_cif->debugSymbols, m_cif->debugDataSpaces,
|
||||||
m_library, &m_errorMessage);
|
m_library, &m_errorMessage);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@@ -188,6 +188,8 @@ bool CdbDumperHelper::moduleLoadHook(const QString &name, bool *ignoreNextBreakP
|
|||||||
} else {
|
} else {
|
||||||
m_state = Failed;
|
m_state = Failed;
|
||||||
}
|
}
|
||||||
|
if (loadDebug)
|
||||||
|
qDebug() << m_state << executionStatusString(m_cif->debugControl);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Loading:
|
case Loading:
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorMessage)
|
bool getModuleList(CIDebugSymbols *syms, QList<Module> *modules, QString *errorMessage)
|
||||||
{
|
{
|
||||||
modules->clear();
|
modules->clear();
|
||||||
ULONG loadedCount, unloadedCount;
|
ULONG loadedCount, unloadedCount;
|
||||||
@@ -80,7 +80,7 @@ bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorM
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search symbols matching a pattern
|
// Search symbols matching a pattern
|
||||||
bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
bool searchSymbols(CIDebugSymbols *syms, const QString &pattern,
|
||||||
QStringList *matches, QString *errorMessage)
|
QStringList *matches, QString *errorMessage)
|
||||||
{
|
{
|
||||||
matches->clear();
|
matches->clear();
|
||||||
@@ -113,7 +113,7 @@ bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
|||||||
|
|
||||||
// Add missing the module specifier: "main" -> "project!main"
|
// Add missing the module specifier: "main" -> "project!main"
|
||||||
|
|
||||||
ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol,
|
ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
// Is it an incomplete symbol?
|
// Is it an incomplete symbol?
|
||||||
@@ -138,7 +138,7 @@ ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List symbols of a module
|
// List symbols of a module
|
||||||
bool getModuleSymbols(IDebugSymbols3 *syms, const QString &moduleName,
|
bool getModuleSymbols(CIDebugSymbols *syms, const QString &moduleName,
|
||||||
QList<Symbol> *symbols, QString *errorMessage)
|
QList<Symbol> *symbols, QString *errorMessage)
|
||||||
{
|
{
|
||||||
// Search all symbols and retrieve addresses
|
// Search all symbols and retrieve addresses
|
||||||
|
@@ -33,8 +33,7 @@
|
|||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -42,9 +41,9 @@ namespace Internal {
|
|||||||
class Module;
|
class Module;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
|
|
||||||
bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorMessage);
|
bool getModuleList(CIDebugSymbols *syms, QList<Module> *modules, QString *errorMessage);
|
||||||
// Search symbols matching a pattern
|
// Search symbols matching a pattern
|
||||||
bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
bool searchSymbols(CIDebugSymbols *syms, const QString &pattern,
|
||||||
QStringList *matches, QString *errorMessage);
|
QStringList *matches, QString *errorMessage);
|
||||||
|
|
||||||
// ResolveSymbol: For symbols that are missing the module specifier,
|
// ResolveSymbol: For symbols that are missing the module specifier,
|
||||||
@@ -53,10 +52,10 @@ bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
|||||||
enum ResolveSymbolResult { ResolveSymbolOk, ResolveSymbolAmbiguous,
|
enum ResolveSymbolResult { ResolveSymbolOk, ResolveSymbolAmbiguous,
|
||||||
ResolveSymbolNotFound, ResolveSymbolError };
|
ResolveSymbolNotFound, ResolveSymbolError };
|
||||||
|
|
||||||
ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol, QString *errorMessage);
|
ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol, QString *errorMessage);
|
||||||
|
|
||||||
// List symbols of a module
|
// List symbols of a module
|
||||||
bool getModuleSymbols(IDebugSymbols3 *syms, const QString &moduleName,
|
bool getModuleSymbols(CIDebugSymbols *syms, const QString &moduleName,
|
||||||
QList<Symbol> *symbols, QString *errorMessage);
|
QList<Symbol> *symbols, QString *errorMessage);
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -33,27 +33,24 @@
|
|||||||
#include "cdbdebugengine_p.h"
|
#include "cdbdebugengine_p.h"
|
||||||
|
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
CdbStackTraceContext::CdbStackTraceContext(IDebugSystemObjects4* pDebugSystemObjects,
|
CdbStackTraceContext::CdbStackTraceContext(CdbComInterfaces *cif) :
|
||||||
IDebugSymbols3* pDebugSymbols) :
|
m_cif(cif),
|
||||||
m_pDebugSystemObjects(pDebugSystemObjects),
|
|
||||||
m_pDebugSymbols(pDebugSymbols),
|
|
||||||
m_instructionOffset(0)
|
m_instructionOffset(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CdbStackTraceContext *CdbStackTraceContext::create(IDebugControl4* pDebugControl,
|
CdbStackTraceContext *CdbStackTraceContext::create(CdbComInterfaces *cif,
|
||||||
IDebugSystemObjects4* pDebugSystemObjects,
|
|
||||||
IDebugSymbols3* pDebugSymbols,
|
|
||||||
unsigned long threadId,
|
unsigned long threadId,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
qDebug() << Q_FUNC_INFO << threadId;
|
qDebug() << Q_FUNC_INFO << threadId;
|
||||||
HRESULT hr = pDebugSystemObjects->SetCurrentThreadId(threadId);
|
HRESULT hr = cif->debugSystemObjects->SetCurrentThreadId(threadId);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = QString::fromLatin1("%1: SetCurrentThreadId %2 failed: %3").
|
*errorMessage = QString::fromLatin1("%1: SetCurrentThreadId %2 failed: %3").
|
||||||
arg(QString::fromLatin1(Q_FUNC_INFO)).
|
arg(QString::fromLatin1(Q_FUNC_INFO)).
|
||||||
@@ -63,8 +60,8 @@ CdbStackTraceContext *CdbStackTraceContext::create(IDebugControl4* pDebugControl
|
|||||||
}
|
}
|
||||||
// fill the DEBUG_STACK_FRAME array
|
// fill the DEBUG_STACK_FRAME array
|
||||||
ULONG frameCount;
|
ULONG frameCount;
|
||||||
CdbStackTraceContext *ctx = new CdbStackTraceContext(pDebugSystemObjects, pDebugSymbols);
|
CdbStackTraceContext *ctx = new CdbStackTraceContext(cif);
|
||||||
hr = pDebugControl->GetStackTrace(0, 0, 0, ctx->m_cdbFrames, CdbStackTraceContext::maxFrames, &frameCount);
|
hr = cif->debugControl->GetStackTrace(0, 0, 0, ctx->m_cdbFrames, CdbStackTraceContext::maxFrames, &frameCount);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
delete ctx;
|
delete ctx;
|
||||||
*errorMessage = msgComFailed("GetStackTrace", hr);
|
*errorMessage = msgComFailed("GetStackTrace", hr);
|
||||||
@@ -100,12 +97,12 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
|
|||||||
m_instructionOffset = instructionOffset;
|
m_instructionOffset = instructionOffset;
|
||||||
frame.address = QString::fromLatin1("0x%1").arg(instructionOffset, 0, 16);
|
frame.address = QString::fromLatin1("0x%1").arg(instructionOffset, 0, 16);
|
||||||
|
|
||||||
m_pDebugSymbols->GetNameByOffsetWide(instructionOffset, wszBuf, MAX_PATH, 0, 0);
|
m_cif->debugSymbols->GetNameByOffsetWide(instructionOffset, wszBuf, MAX_PATH, 0, 0);
|
||||||
frame.function = QString::fromUtf16(wszBuf);
|
frame.function = QString::fromUtf16(wszBuf);
|
||||||
|
|
||||||
ULONG ulLine;
|
ULONG ulLine;
|
||||||
ULONG64 ul64Displacement;
|
ULONG64 ul64Displacement;
|
||||||
const HRESULT hr = m_pDebugSymbols->GetLineByOffsetWide(instructionOffset, &ulLine, wszBuf, MAX_PATH, 0, &ul64Displacement);
|
const HRESULT hr = m_cif->debugSymbols->GetLineByOffsetWide(instructionOffset, &ulLine, wszBuf, MAX_PATH, 0, &ul64Displacement);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
frame.line = ulLine;
|
frame.line = ulLine;
|
||||||
// Vitally important to use canonical file that matches editormanager,
|
// Vitally important to use canonical file that matches editormanager,
|
||||||
@@ -131,7 +128,7 @@ CdbSymbolGroupContext *CdbStackTraceContext::symbolGroupContextAt(int index, QSt
|
|||||||
|
|
||||||
if (m_symbolContexts.at(index))
|
if (m_symbolContexts.at(index))
|
||||||
return m_symbolContexts.at(index);
|
return m_symbolContexts.at(index);
|
||||||
IDebugSymbolGroup2 *sg = createSymbolGroup(index, errorMessage);
|
CIDebugSymbolGroup *sg = createSymbolGroup(index, errorMessage);
|
||||||
if (!sg)
|
if (!sg)
|
||||||
return 0;
|
return 0;
|
||||||
CdbSymbolGroupContext *sc = CdbSymbolGroupContext::create(QLatin1String("local"), sg, errorMessage);
|
CdbSymbolGroupContext *sc = CdbSymbolGroupContext::create(QLatin1String("local"), sg, errorMessage);
|
||||||
@@ -141,23 +138,23 @@ CdbSymbolGroupContext *CdbStackTraceContext::symbolGroupContextAt(int index, QSt
|
|||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDebugSymbolGroup2 *CdbStackTraceContext::createSymbolGroup(int index, QString *errorMessage)
|
CIDebugSymbolGroup *CdbStackTraceContext::createSymbolGroup(int index, QString *errorMessage)
|
||||||
{
|
{
|
||||||
IDebugSymbolGroup2 *sg = 0;
|
CIDebugSymbolGroup *sg = 0;
|
||||||
HRESULT hr = m_pDebugSymbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_LOCALS, NULL, &sg);
|
HRESULT hr = m_cif->debugSymbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_LOCALS, NULL, &sg);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = msgComFailed("GetScopeSymbolGroup", hr);
|
*errorMessage = msgComFailed("GetScopeSymbolGroup", hr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_pDebugSymbols->SetScope(0, m_cdbFrames + index, NULL, 0);
|
hr = m_cif->debugSymbols->SetScope(0, m_cdbFrames + index, NULL, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = msgComFailed("SetScope", hr);
|
*errorMessage = msgComFailed("SetScope", hr);
|
||||||
sg->Release();
|
sg->Release();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// refresh with current frame
|
// refresh with current frame
|
||||||
hr = m_pDebugSymbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_LOCALS, sg, &sg);
|
hr = m_cif->debugSymbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_LOCALS, sg, &sg);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = msgComFailed("GetScopeSymbolGroup", hr);
|
*errorMessage = msgComFailed("GetScopeSymbolGroup", hr);
|
||||||
sg->Release();
|
sg->Release();
|
||||||
@@ -166,5 +163,34 @@ IDebugSymbolGroup2 *CdbStackTraceContext::createSymbolGroup(int index, QString *
|
|||||||
return sg;
|
return sg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CdbStackTraceContext::toString() const
|
||||||
|
{
|
||||||
|
QString rc;
|
||||||
|
QTextStream str(&rc);
|
||||||
|
format(str);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CdbStackTraceContext::format(QTextStream &str) const
|
||||||
|
{
|
||||||
|
const int count = m_frames.count();
|
||||||
|
const int defaultFieldWidth = str.fieldWidth();
|
||||||
|
const QTextStream::FieldAlignment defaultAlignment = str.fieldAlignment();
|
||||||
|
for (int f = 0; f < count; f++) {
|
||||||
|
const StackFrame &frame = m_frames.at(f);
|
||||||
|
const bool hasFile = !frame.file.isEmpty();
|
||||||
|
// left-pad level
|
||||||
|
str << qSetFieldWidth(6) << left << f;
|
||||||
|
str.setFieldWidth(defaultFieldWidth);
|
||||||
|
str.setFieldAlignment(defaultAlignment);
|
||||||
|
if (hasFile)
|
||||||
|
str << QDir::toNativeSeparators(frame.file) << ':' << frame.line << " (";
|
||||||
|
str << frame.function;
|
||||||
|
if (hasFile)
|
||||||
|
str << ')';
|
||||||
|
str << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -32,15 +32,19 @@
|
|||||||
|
|
||||||
#include "stackhandler.h"
|
#include "stackhandler.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QTextStream;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
struct CdbComInterfaces;
|
||||||
class CdbSymbolGroupContext;
|
class CdbSymbolGroupContext;
|
||||||
|
|
||||||
/* Context representing a break point stack consisting of several frames.
|
/* Context representing a break point stack consisting of several frames.
|
||||||
@@ -51,15 +55,12 @@ class CdbStackTraceContext
|
|||||||
{
|
{
|
||||||
Q_DISABLE_COPY(CdbStackTraceContext)
|
Q_DISABLE_COPY(CdbStackTraceContext)
|
||||||
|
|
||||||
explicit CdbStackTraceContext(IDebugSystemObjects4* pDebugSystemObjects,
|
explicit CdbStackTraceContext(CdbComInterfaces *cif);
|
||||||
IDebugSymbols3* pDebugSymbols);
|
|
||||||
public:
|
public:
|
||||||
enum { maxFrames = 100 };
|
enum { maxFrames = 100 };
|
||||||
|
|
||||||
~CdbStackTraceContext();
|
~CdbStackTraceContext();
|
||||||
static CdbStackTraceContext *create(IDebugControl4* pDebugControl,
|
static CdbStackTraceContext *create(CdbComInterfaces *cif,
|
||||||
IDebugSystemObjects4* pDebugSystemObjects,
|
|
||||||
IDebugSymbols3* pDebugSymbols,
|
|
||||||
unsigned long threadid,
|
unsigned long threadid,
|
||||||
QString *errorMessage);
|
QString *errorMessage);
|
||||||
|
|
||||||
@@ -71,12 +72,15 @@ public:
|
|||||||
|
|
||||||
CdbSymbolGroupContext *symbolGroupContextAt(int index, QString *errorMessage);
|
CdbSymbolGroupContext *symbolGroupContextAt(int index, QString *errorMessage);
|
||||||
|
|
||||||
|
// Format for logging
|
||||||
|
void format(QTextStream &str) const;
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool init(unsigned long frameCount, QString *errorMessage);
|
bool init(unsigned long frameCount, QString *errorMessage);
|
||||||
IDebugSymbolGroup2 *createSymbolGroup(int index, QString *errorMessage);
|
CIDebugSymbolGroup *createSymbolGroup(int index, QString *errorMessage);
|
||||||
|
|
||||||
IDebugSystemObjects4* m_pDebugSystemObjects;
|
CdbComInterfaces *m_cif;
|
||||||
IDebugSymbols3* m_pDebugSymbols;
|
|
||||||
|
|
||||||
DEBUG_STACK_FRAME m_cdbFrames[maxFrames];
|
DEBUG_STACK_FRAME m_cdbFrames[maxFrames];
|
||||||
QVector <CdbSymbolGroupContext*> m_symbolContexts;
|
QVector <CdbSymbolGroupContext*> m_symbolContexts;
|
||||||
|
@@ -105,7 +105,7 @@ static inline CdbSymbolGroupContext::SymbolState getSymbolState(const DEBUG_SYMB
|
|||||||
}
|
}
|
||||||
|
|
||||||
CdbSymbolGroupContext::CdbSymbolGroupContext(const QString &prefix,
|
CdbSymbolGroupContext::CdbSymbolGroupContext(const QString &prefix,
|
||||||
IDebugSymbolGroup2 *symbolGroup) :
|
CIDebugSymbolGroup *symbolGroup) :
|
||||||
m_prefix(prefix),
|
m_prefix(prefix),
|
||||||
m_nameDelimiter(QLatin1Char('.')),
|
m_nameDelimiter(QLatin1Char('.')),
|
||||||
m_symbolGroup(symbolGroup)
|
m_symbolGroup(symbolGroup)
|
||||||
@@ -118,7 +118,7 @@ CdbSymbolGroupContext::~CdbSymbolGroupContext()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CdbSymbolGroupContext *CdbSymbolGroupContext::create(const QString &prefix,
|
CdbSymbolGroupContext *CdbSymbolGroupContext::create(const QString &prefix,
|
||||||
IDebugSymbolGroup2 *symbolGroup,
|
CIDebugSymbolGroup *symbolGroup,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
CdbSymbolGroupContext *rc= new CdbSymbolGroupContext(prefix, symbolGroup);
|
CdbSymbolGroupContext *rc= new CdbSymbolGroupContext(prefix, symbolGroup);
|
||||||
@@ -343,7 +343,7 @@ QString CdbSymbolGroupContext::symbolINameAt(unsigned long index) const
|
|||||||
return m_inameIndexMap.key(index);
|
return m_inameIndexMap.key(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString hexSymbolOffset(IDebugSymbolGroup2 *sg, unsigned long index)
|
static inline QString hexSymbolOffset(CIDebugSymbolGroup *sg, unsigned long index)
|
||||||
{
|
{
|
||||||
ULONG64 rc = 0;
|
ULONG64 rc = 0;
|
||||||
if (FAILED(sg->GetSymbolOffset(index, &rc)))
|
if (FAILED(sg->GetSymbolOffset(index, &rc)))
|
||||||
@@ -436,7 +436,7 @@ template <class Integer>
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl,
|
QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, CIDebugControl *ctl,
|
||||||
QString *qType,
|
QString *qType,
|
||||||
int integerBase)
|
int integerBase)
|
||||||
{
|
{
|
||||||
|
@@ -30,8 +30,7 @@
|
|||||||
#ifndef CDBSYMBOLGROUPCONTEXT_H
|
#ifndef CDBSYMBOLGROUPCONTEXT_H
|
||||||
#define CDBSYMBOLGROUPCONTEXT_H
|
#define CDBSYMBOLGROUPCONTEXT_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include "cdbcom.h"
|
||||||
#include <inc/dbgeng.h>
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
@@ -60,12 +59,12 @@ class CdbSymbolGroupContext
|
|||||||
{
|
{
|
||||||
Q_DISABLE_COPY(CdbSymbolGroupContext);
|
Q_DISABLE_COPY(CdbSymbolGroupContext);
|
||||||
explicit CdbSymbolGroupContext(const QString &prefix,
|
explicit CdbSymbolGroupContext(const QString &prefix,
|
||||||
IDebugSymbolGroup2 *symbolGroup);
|
CIDebugSymbolGroup *symbolGroup);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~CdbSymbolGroupContext();
|
~CdbSymbolGroupContext();
|
||||||
static CdbSymbolGroupContext *create(const QString &prefix,
|
static CdbSymbolGroupContext *create(const QString &prefix,
|
||||||
IDebugSymbolGroup2 *symbolGroup,
|
CIDebugSymbolGroup *symbolGroup,
|
||||||
QString *errorMessage);
|
QString *errorMessage);
|
||||||
|
|
||||||
QString prefix() const { return m_prefix; }
|
QString prefix() const { return m_prefix; }
|
||||||
@@ -92,7 +91,7 @@ public:
|
|||||||
inline bool isExpanded(const QString &prefix) const { return symbolState(prefix) == ExpandedSymbol; }
|
inline bool isExpanded(const QString &prefix) const { return symbolState(prefix) == ExpandedSymbol; }
|
||||||
|
|
||||||
// Helper to convert a DEBUG_VALUE structure to a string representation
|
// Helper to convert a DEBUG_VALUE structure to a string representation
|
||||||
static QString debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl, QString *type = 0, int integerBase = 10);
|
static QString debugValueToString(const DEBUG_VALUE &dv, CIDebugControl *ctl, QString *type = 0, int integerBase = 10);
|
||||||
|
|
||||||
// format an array of unsigned longs as "0x323, 0x2322, ..."
|
// format an array of unsigned longs as "0x323, 0x2322, ..."
|
||||||
static QString hexFormatArray(const unsigned short *array, int size);
|
static QString hexFormatArray(const unsigned short *array, int size);
|
||||||
@@ -121,7 +120,7 @@ private:
|
|||||||
const QString m_prefix;
|
const QString m_prefix;
|
||||||
const QChar m_nameDelimiter;
|
const QChar m_nameDelimiter;
|
||||||
|
|
||||||
IDebugSymbolGroup2 *m_symbolGroup;
|
CIDebugSymbolGroup *m_symbolGroup;
|
||||||
NameIndexMap m_inameIndexMap;
|
NameIndexMap m_inameIndexMap;
|
||||||
QVector<DEBUG_SYMBOL_PARAMETERS> m_symbolParameters;
|
QVector<DEBUG_SYMBOL_PARAMETERS> m_symbolParameters;
|
||||||
};
|
};
|
||||||
|
@@ -8,6 +8,8 @@ include(../../qworkbenchlibrary.pri)
|
|||||||
linux-* {
|
linux-* {
|
||||||
CONFIG -= release
|
CONFIG -= release
|
||||||
CONFIG += debug
|
CONFIG += debug
|
||||||
|
# The following line works around a linker issue with gcc 4.1.2
|
||||||
|
QMAKE_CXXFLAGS *= -O2
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCES += ../../../share/qtcreator/gdbmacros/gdbmacros.cpp
|
SOURCES += ../../../share/qtcreator/gdbmacros/gdbmacros.cpp
|
||||||
|
@@ -3173,7 +3173,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
|||||||
sendWatchParameters(params);
|
sendWatchParameters(params);
|
||||||
|
|
||||||
QString cmd ="call "
|
QString cmd ="call "
|
||||||
+ QString("qDumpObjectData440(")
|
+ QString("(void*)qDumpObjectData440(")
|
||||||
+ QString::number(protocol)
|
+ QString::number(protocol)
|
||||||
+ ',' + "%1+1" // placeholder for token
|
+ ',' + "%1+1" // placeholder for token
|
||||||
+ ',' + addr
|
+ ',' + addr
|
||||||
@@ -3469,7 +3469,7 @@ void GdbEngine::sendWatchParameters(const QByteArray ¶ms0)
|
|||||||
QByteArray params = params0;
|
QByteArray params = params0;
|
||||||
params.append('\0');
|
params.append('\0');
|
||||||
char buf[50];
|
char buf[50];
|
||||||
sprintf(buf, "set {char[%d]} qDumpInBuffer = {", params.size());
|
sprintf(buf, "set {char[%d]} &qDumpInBuffer = {", params.size());
|
||||||
QByteArray encoded;
|
QByteArray encoded;
|
||||||
encoded.append(buf);
|
encoded.append(buf);
|
||||||
for (int i = 0; i != params.size(); ++i) {
|
for (int i = 0; i != params.size(); ++i) {
|
||||||
@@ -4177,14 +4177,14 @@ void GdbEngine::tryLoadDebuggingHelpers()
|
|||||||
sendCommand("sharedlibrary " + dotEscape(lib));
|
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||||
#endif
|
#endif
|
||||||
// retreive list of dumpable classes
|
// retreive list of dumpable classes
|
||||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
sendCommand("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
||||||
sendCommand("p (char*)&qDumpOutBuffer", GdbQueryDebuggingHelper);
|
sendCommand("p (char*)&qDumpOutBuffer", GdbQueryDebuggingHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::recheckDebuggingHelperAvailability()
|
void GdbEngine::recheckDebuggingHelperAvailability()
|
||||||
{
|
{
|
||||||
// retreive list of dumpable classes
|
// retreive list of dumpable classes
|
||||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
sendCommand("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
||||||
sendCommand("p (char*)&qDumpOutBuffer", GdbQueryDebuggingHelper);
|
sendCommand("p (char*)&qDumpOutBuffer", GdbQueryDebuggingHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1554,7 +1554,7 @@ void ProjectExplorerPlugin::updateRecentProjectMenu()
|
|||||||
const QPair<QString, QString> &s = *it;
|
const QPair<QString, QString> &s = *it;
|
||||||
if (s.first.endsWith(".qws"))
|
if (s.first.endsWith(".qws"))
|
||||||
continue;
|
continue;
|
||||||
QAction *action = menu->addAction(s.second);
|
QAction *action = menu->addAction(s.first);
|
||||||
action->setData(s.first);
|
action->setData(s.first);
|
||||||
connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
|
connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user