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.
|
||||
|
||||
A more detailed list of changes follows below. If you want to know
|
||||
the exact and complete list of changes, you can check out the QtCreator
|
||||
sources from the public git repository and check the logs, e.g.
|
||||
A more detailed list of changes follows below. If you want to know the exact
|
||||
and complete list of changes, you can check out the QtCreator sources from the
|
||||
public git repository and check the logs, e.g.
|
||||
|
||||
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,
|
||||
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
|
||||
This release introduces source and binary incompatible changes to the plugin
|
||||
API, so if you created your own custom plugins these need to be adapted.
|
||||
|
||||
Editing
|
||||
* Added support for JavaScript.
|
||||
* Added syntax highlighting and code completion for qdoc and doxygen tags.
|
||||
* Improved function argument hint.
|
||||
* More checkpoints in editor history.
|
||||
* Ctrl-click for jumping to a symbol definition.
|
||||
* Improved open documents view (sorted, single-click, close buttons).
|
||||
* Copying text from the context help browser and output windows didn't work.
|
||||
* Completely reworked editor split mechanism
|
||||
* Added support for JavaScript
|
||||
* Added syntax highlighting and code completion for qdoc and doxygen tags
|
||||
* Improved function argument hint
|
||||
* Added more checkpoints in editor history
|
||||
* Added Ctrl-click for jumping to a symbol definition
|
||||
* 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
|
||||
* Experimental support for generic Makefile based projects.
|
||||
* Improved .pro file parsing, handling scopes and $$system directive.
|
||||
* Support subdir.file in .pro files.
|
||||
* Option to start application in external terminal.
|
||||
* Added experimental support for generic Makefile based projects
|
||||
* Improved .pro file parsing, handling scopes and $$system directive
|
||||
* Added support for subdir.file in .pro files
|
||||
* Added an option to start the application in an external terminal
|
||||
* Improved CMake support
|
||||
|
||||
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,
|
||||
no dumper buildstep anymore.
|
||||
* New dumper for std::set. Improved QString, QVariant, std::wstring
|
||||
* Make strategy to load shared objects configurable (auto-solib-add).
|
||||
* Increase number of shown stack frames on request instead of loading them all.
|
||||
* Improved interaction in the Locals&Watchers view.
|
||||
no dumper buildstep anymore
|
||||
* Added a dumper for std::set and improved dumpers for QString, QVariant,
|
||||
std::wstring
|
||||
* Made strategy to load shared objects configurable (auto-solib-add)
|
||||
* The number of shown stack frames is now increased on request instead of
|
||||
loading them all
|
||||
* Improved interaction in the Locals & Watchers view
|
||||
|
||||
Wizards
|
||||
* It is now possible to choose file suffixes in the options dialog.
|
||||
* Code of language change event is now generated correctly (added call
|
||||
to base class).
|
||||
* Generated header guards now adapt to file extension.
|
||||
* It is now possible to choose default file suffixes in the options dialog
|
||||
* Fixed the code that was generated for handling a language change event
|
||||
(added call to base class)
|
||||
* Generated header guards now adapt to file extension
|
||||
|
||||
Designer
|
||||
* Added signal/slot editor.
|
||||
* Fixed "Goto slot" (formatting/multiple inheritance).
|
||||
* Context help for form editor widgets.
|
||||
* Added signal/slot editor
|
||||
* Fixed "Goto slot" (formatting/multiple inheritance)
|
||||
* Context help for form editor widgets
|
||||
|
||||
Version control plugins
|
||||
* Fixed handling of colored git output.
|
||||
* Made svn 1.6 work.
|
||||
* Added syntax highlighting to the git submit editor.
|
||||
* Made git submit editor remove comment lines.
|
||||
* Fixed handling of colored git output
|
||||
* Added syntax highlighting to the git submit editor
|
||||
* Made git submit editor remove comment lines
|
||||
* Made Subversion 1.6 work
|
||||
* Added configuration options for submit editors (user fields, word
|
||||
wrapping).
|
||||
wrapping)
|
||||
|
||||
|
||||
Platform Specific
|
||||
|
||||
Mac
|
||||
* Don't override systems Hide action.
|
||||
* Option to set DYLD_IMAGE_SUFFIX=_debug when running applications.
|
||||
* Open in Finder action in project tree.
|
||||
* The system's Hide action is no longer overridden
|
||||
* Added option to set DYLD_IMAGE_SUFFIX=_debug when running applications
|
||||
* Added Open in Finder action in project tree
|
||||
|
||||
Linux
|
||||
* Don't crash because of incompatible libQt3Support:
|
||||
Provide a wrapper script and ship libQt3Support.
|
||||
(Fixes crashes e.g. in file dialogs on openSUSE 11.1)
|
||||
* Fixed crash because of incompatible libQt3Support, by providing a wrapper
|
||||
script and shipping libQt3Support.
|
||||
(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:
|
||||
* Martin Aumueller <aumuell@reserv.at> (FakeVim improvements)
|
||||
* 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)
|
||||
|
||||
TEMPLATE = app
|
||||
|
@@ -110,8 +110,9 @@ QProcess *CMakeManager::createXmlFile(const QStringList &arguments, const QStrin
|
||||
QString buildDirectoryPath = buildDirectory.absolutePath();
|
||||
qDebug()<<"Creating cbp file in"<<buildDirectoryPath;
|
||||
buildDirectory.mkpath(buildDirectoryPath);
|
||||
QProcess * cmake = new QProcess;
|
||||
QProcess *cmake = new QProcess;
|
||||
cmake->setWorkingDirectory(buildDirectoryPath);
|
||||
cmake->setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
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)
|
||||
|
||||
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>"
|
||||
"<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, "
|
||||
|
@@ -604,6 +604,13 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &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;
|
||||
|
||||
QTextBlock block;
|
||||
|
@@ -27,6 +27,7 @@ INCLUDEPATH*=$$PWD
|
||||
CDB_LIBPATH=$$CDB_PATH/lib/$$CDB_PLATFORM
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/cdbcom.h \
|
||||
$$PWD/cdbdebugengine.h \
|
||||
$$PWD/cdbdebugengine_p.h \
|
||||
$$PWD/cdbdebugeventcallback.h \
|
||||
|
@@ -42,8 +42,8 @@ namespace Internal {
|
||||
|
||||
typedef QList<DisassemblerLine> DisassemblerLineList;
|
||||
|
||||
bool getRegisters(IDebugControl4 *ctl,
|
||||
IDebugRegisters2 *ireg,
|
||||
bool getRegisters(CIDebugControl *ctl,
|
||||
CIDebugRegisters *ireg,
|
||||
QList<Register> *registers,
|
||||
QString *errorMessage, int base)
|
||||
{
|
||||
@@ -194,8 +194,8 @@ void DisassemblerOutputParser::parse(const QStringList &l)
|
||||
}
|
||||
}
|
||||
|
||||
bool dissassemble(IDebugClient5 *client,
|
||||
IDebugControl4 *ctl,
|
||||
bool dissassemble(CIDebugClient *client,
|
||||
CIDebugControl *ctl,
|
||||
ULONG64 offset,
|
||||
unsigned long beforeLines,
|
||||
unsigned long afterLines,
|
||||
|
@@ -33,8 +33,7 @@
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -44,14 +43,14 @@ class DisassemblerLine;
|
||||
// Utilities related to assembler code.
|
||||
class Register;
|
||||
|
||||
bool getRegisters(IDebugControl4 *ctl,
|
||||
IDebugRegisters2 *ireg,
|
||||
bool getRegisters(CIDebugControl *ctl,
|
||||
CIDebugRegisters *ireg,
|
||||
QList<Register> *registers,
|
||||
QString *errorMessage,
|
||||
int base = 10 /* 16 for hex, etc */);
|
||||
|
||||
bool dissassemble(IDebugClient5 *client,
|
||||
IDebugControl4 *ctl,
|
||||
bool dissassemble(CIDebugClient *client,
|
||||
CIDebugControl *ctl,
|
||||
ULONG64 offset,
|
||||
unsigned long beforeLines,
|
||||
unsigned long afterLines,
|
||||
|
@@ -131,7 +131,7 @@ QString CDBBreakPoint::expression() const
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool CDBBreakPoint::apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const
|
||||
bool CDBBreakPoint::apply(CIDebugBreakpoint *ibp, QString *errorMessage) const
|
||||
{
|
||||
const QString expr = expression();
|
||||
if (debugCDB)
|
||||
@@ -148,7 +148,7 @@ bool CDBBreakPoint::apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDBBreakPoint::add(IDebugControl4* debugControl, QString *errorMessage) const
|
||||
bool CDBBreakPoint::add(CIDebugControl* debugControl, QString *errorMessage) const
|
||||
{
|
||||
IDebugBreakpoint2* ibp = 0;
|
||||
const HRESULT hr = debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &ibp);
|
||||
@@ -176,7 +176,7 @@ QString CDBBreakPoint::canonicalSourceFile(const QString &f)
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool CDBBreakPoint::retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage)
|
||||
bool CDBBreakPoint::retrieve(CIDebugBreakpoint *ibp, QString *errorMessage)
|
||||
{
|
||||
clear();
|
||||
WCHAR wszBuf[MAX_PATH];
|
||||
@@ -245,7 +245,7 @@ bool CDBBreakPoint::parseExpression(const QString &expr)
|
||||
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);
|
||||
if (FAILED(hr)) {
|
||||
@@ -257,7 +257,7 @@ bool CDBBreakPoint::getBreakPointCount(IDebugControl4* debugControl, ULONG *coun
|
||||
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;
|
||||
bps->clear();
|
||||
|
@@ -30,8 +30,7 @@
|
||||
#ifndef CDBBREAKPOINTS_H
|
||||
#define CDBBREAKPOINTS_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QList>
|
||||
@@ -64,16 +63,16 @@ struct CDBBreakPoint
|
||||
// Apply parameters
|
||||
bool apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const;
|
||||
// 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
|
||||
bool retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage);
|
||||
bool parseExpression(const QString &expr);
|
||||
// Retrieve all breakpoints from the engine
|
||||
static bool getBreakPointCount(IDebugControl4* debugControl, ULONG *count, QString *errorMessage = 0);
|
||||
static bool getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
|
||||
static bool getBreakPointCount(CIDebugControl* debugControl, ULONG *count, QString *errorMessage = 0);
|
||||
static bool getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
|
||||
// Synchronize (halted) engine with BreakHandler.
|
||||
static bool synchronizeBreakPoints(IDebugControl4* ctl, IDebugSymbols3 *syms,
|
||||
static bool synchronizeBreakPoints(CIDebugControl* ctl, CIDebugSymbols *syms,
|
||||
BreakHandler *bh, QString *errorMessage);
|
||||
|
||||
// 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
|
||||
|
||||
static inline ULONG getInterruptTimeOutSecs(IDebugControl4 *ctl)
|
||||
static inline ULONG getInterruptTimeOutSecs(CIDebugControl *ctl)
|
||||
{
|
||||
ULONG rc = 0;
|
||||
ctl->GetInterruptTimeout(&rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline bool getExecutionStatus(IDebugControl4 *ctl,
|
||||
ULONG *executionStatus,
|
||||
QString *errorMessage)
|
||||
bool getExecutionStatus(CIDebugControl *ctl,
|
||||
ULONG *executionStatus,
|
||||
QString *errorMessage /* = 0 */)
|
||||
{
|
||||
const HRESULT hr = ctl->GetExecutionStatus(executionStatus);
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = msgComFailed("GetExecutionStatus", hr);
|
||||
if (errorMessage)
|
||||
*errorMessage = msgComFailed("GetExecutionStatus", hr);
|
||||
return false;
|
||||
}
|
||||
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() :
|
||||
m_debugCreate(0)
|
||||
@@ -189,7 +238,7 @@ bool DebuggerEngineLibrary::init(const QString &path, QString *errorMessage)
|
||||
}
|
||||
|
||||
// ----- SyntaxSetter
|
||||
SyntaxSetter::SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax) :
|
||||
SyntaxSetter::SyntaxSetter(CIDebugControl *ctl, ULONG desiredSyntax) :
|
||||
m_desiredSyntax(desiredSyntax),
|
||||
m_ctl(ctl)
|
||||
{
|
||||
@@ -385,8 +434,10 @@ void CdbDebugEngine::shutdown()
|
||||
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()
|
||||
@@ -939,7 +990,7 @@ void CdbDebugEngine::executeDebuggerCommand(const QString &command)
|
||||
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)
|
||||
qDebug() << Q_FUNC_INFO << command;
|
||||
@@ -1186,6 +1237,10 @@ void CdbDebugEngine::reloadRegisters()
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
@@ -1319,8 +1374,7 @@ void CdbDebugEnginePrivate::updateStackTrace()
|
||||
QString errorMessage;
|
||||
m_engine->reloadRegisters();
|
||||
m_currentStackTrace =
|
||||
CdbStackTraceContext::create(m_cif.debugControl, m_cif.debugSystemObjects,
|
||||
m_cif.debugSymbols, m_currentThreadId, &errorMessage);
|
||||
CdbStackTraceContext::create(&m_cif, m_currentThreadId, &errorMessage);
|
||||
if (!m_currentStackTrace) {
|
||||
qWarning("%s: failed to create trace context: %s", Q_FUNC_INFO, qPrintable(errorMessage));
|
||||
return;
|
||||
|
@@ -73,11 +73,11 @@ private:
|
||||
class SyntaxSetter {
|
||||
Q_DISABLE_COPY(SyntaxSetter)
|
||||
public:
|
||||
explicit inline SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax);
|
||||
explicit inline SyntaxSetter(CIDebugControl *ctl, ULONG desiredSyntax);
|
||||
inline ~SyntaxSetter();
|
||||
private:
|
||||
const ULONG m_desiredSyntax;
|
||||
IDebugControl4 *m_ctl;
|
||||
CIDebugControl *m_ctl;
|
||||
ULONG m_oldSyntax;
|
||||
};
|
||||
|
||||
@@ -85,12 +85,12 @@ private:
|
||||
struct CdbComInterfaces
|
||||
{
|
||||
CdbComInterfaces();
|
||||
IDebugClient5* debugClient;
|
||||
IDebugControl4* debugControl;
|
||||
IDebugSystemObjects4* debugSystemObjects;
|
||||
IDebugSymbols3* debugSymbols;
|
||||
IDebugRegisters2* debugRegisters;
|
||||
IDebugDataSpaces4* debugDataSpaces;
|
||||
CIDebugClient* debugClient;
|
||||
CIDebugControl* debugControl;
|
||||
CIDebugSystemObjects* debugSystemObjects;
|
||||
CIDebugSymbols* debugSymbols;
|
||||
CIDebugRegisters* debugRegisters;
|
||||
CIDebugDataSpaces* debugDataSpaces;
|
||||
};
|
||||
|
||||
struct CdbDebugEnginePrivate
|
||||
@@ -130,7 +130,7 @@ struct CdbDebugEnginePrivate
|
||||
|
||||
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;
|
||||
HANDLE m_hDebuggeeProcess;
|
||||
@@ -154,6 +154,12 @@ struct CdbDebugEnginePrivate
|
||||
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
|
||||
QString msgDebugEngineComResult(HRESULT hr);
|
||||
QString msgComFailed(const char *func, HRESULT hr);
|
||||
|
@@ -32,8 +32,12 @@
|
||||
#include "cdbdebugengine_p.h"
|
||||
#include "debuggermanager.h"
|
||||
#include "breakhandler.h"
|
||||
#include "cdbstacktracecontext.h"
|
||||
|
||||
enum { cppExceptionCode = 0xe06d7363 };
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -198,7 +202,7 @@ STDMETHODIMP CdbDebugEventCallbackBase::ChangeSymbolState(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(IDebugClient5 *clnt)
|
||||
IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(CIDebugClient *clnt)
|
||||
{
|
||||
IDebugEventCallbacksWide *rc = 0;
|
||||
if (SUCCEEDED(clnt->GetEventCallbacksWide(&rc)))
|
||||
@@ -231,26 +235,116 @@ STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT2 Bp)
|
||||
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").
|
||||
arg(QString::number(Exception->ExceptionCode, 16)).
|
||||
arg(FirstChance);
|
||||
str.setIntegerBase(16);
|
||||
str << "\nException at 0x" << e->ExceptionAddress
|
||||
<< ", 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(
|
||||
THIS_
|
||||
__in PEXCEPTION_RECORD64 Exception,
|
||||
__in ULONG FirstChance
|
||||
__in ULONG /* FirstChance */
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Exception)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << msgException(Exception, FirstChance);
|
||||
|
||||
// First chance are harmless
|
||||
if (!FirstChance)
|
||||
qWarning("%s", qPrintable(msgException(Exception, FirstChance)));
|
||||
QString msg;
|
||||
{
|
||||
QTextStream str(&msg);
|
||||
formatException(Exception, m_pEngine->m_d->m_cif, str);
|
||||
}
|
||||
m_pEngine->m_d->m_debuggerManagerAccess->showApplicationOutput(msg);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -395,7 +489,7 @@ STDMETHODIMP IgnoreDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
||||
}
|
||||
|
||||
// --------- EventCallbackRedirector
|
||||
EventCallbackRedirector::EventCallbackRedirector(IDebugClient5 *client, IDebugEventCallbacksWide *cb) :
|
||||
EventCallbackRedirector::EventCallbackRedirector(CIDebugClient *client, IDebugEventCallbacksWide *cb) :
|
||||
m_client(client),
|
||||
m_oldCb(CdbDebugEventCallbackBase::getEventCallback(client))
|
||||
{
|
||||
|
@@ -30,8 +30,8 @@
|
||||
#ifndef DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||
#define DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
namespace Debugger {
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
);
|
||||
|
||||
|
||||
static IDebugEventCallbacksWide *getEventCallback(IDebugClient5 *clnt);
|
||||
static IDebugEventCallbacksWide *getEventCallback(CIDebugClient *clnt);
|
||||
};
|
||||
|
||||
class CdbDebugEventCallback : public CdbDebugEventCallbackBase
|
||||
@@ -252,10 +252,10 @@ public:
|
||||
class EventCallbackRedirector {
|
||||
Q_DISABLE_COPY(EventCallbackRedirector)
|
||||
public:
|
||||
explicit EventCallbackRedirector(IDebugClient5 *client, IDebugEventCallbacksWide *cb);
|
||||
explicit EventCallbackRedirector(CIDebugClient *client, IDebugEventCallbacksWide *cb);
|
||||
~EventCallbackRedirector();
|
||||
private:
|
||||
IDebugClient5 *m_client;
|
||||
CIDebugClient *m_client;
|
||||
IDebugEventCallbacksWide *m_oldCb;
|
||||
};
|
||||
|
||||
|
@@ -84,7 +84,7 @@ STDMETHODIMP CdbDebugOutputBase::Output(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IDebugOutputCallbacksWide *CdbDebugOutputBase::getOutputCallback(IDebugClient5 *client)
|
||||
IDebugOutputCallbacksWide *CdbDebugOutputBase::getOutputCallback(CIDebugClient *client)
|
||||
{
|
||||
IDebugOutputCallbacksWide *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
|
||||
// as long as in scope
|
||||
OutputRedirector::OutputRedirector(IDebugClient5 *client, IDebugOutputCallbacksWide *newHandler) :
|
||||
OutputRedirector::OutputRedirector(CIDebugClient *client, IDebugOutputCallbacksWide *newHandler) :
|
||||
m_client(client),
|
||||
m_oldHandler(CdbDebugOutputBase::getOutputCallback(client))
|
||||
{
|
||||
|
@@ -30,8 +30,7 @@
|
||||
#ifndef DEBUGGER_CDBOUTPUT_H
|
||||
#define DEBUGGER_CDBOUTPUT_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
@@ -65,7 +64,7 @@ public:
|
||||
);
|
||||
|
||||
// Helpers to retrieve the output callbacks IF
|
||||
static IDebugOutputCallbacksWide *getOutputCallback(IDebugClient5 *client);
|
||||
static IDebugOutputCallbacksWide *getOutputCallback(CIDebugClient *client);
|
||||
|
||||
protected:
|
||||
CdbDebugOutputBase();
|
||||
@@ -110,10 +109,10 @@ private:
|
||||
class OutputRedirector {
|
||||
Q_DISABLE_COPY(OutputRedirector)
|
||||
public:
|
||||
explicit OutputRedirector(IDebugClient5 *client, IDebugOutputCallbacksWide *newHandler);
|
||||
explicit OutputRedirector(CIDebugClient *client, IDebugOutputCallbacksWide *newHandler);
|
||||
~OutputRedirector();
|
||||
private:
|
||||
IDebugClient5 *m_client;
|
||||
CIDebugClient *m_client;
|
||||
IDebugOutputCallbacksWide *m_oldHandler;
|
||||
};
|
||||
|
||||
|
@@ -42,8 +42,8 @@ namespace Internal {
|
||||
|
||||
// Alloc memory in debuggee using the ".dvalloc" command as
|
||||
// there seems to be no API for it.
|
||||
static bool allocDebuggeeMemory(IDebugControl4 *ctl,
|
||||
IDebugClient5 *client,
|
||||
static bool allocDebuggeeMemory(CIDebugControl *ctl,
|
||||
CIDebugClient *client,
|
||||
int size, ULONG64 *address, QString *errorMessage)
|
||||
{
|
||||
*address = 0;
|
||||
@@ -69,9 +69,9 @@ static bool allocDebuggeeMemory(IDebugControl4 *ctl,
|
||||
}
|
||||
|
||||
// Alloc an AscII string in debuggee
|
||||
static bool createDebuggeeAscIIString(IDebugControl4 *ctl,
|
||||
IDebugClient5 *client,
|
||||
IDebugDataSpaces4 *data,
|
||||
static bool createDebuggeeAscIIString(CIDebugControl *ctl,
|
||||
CIDebugClient *client,
|
||||
CIDebugDataSpaces *data,
|
||||
const QString &s,
|
||||
ULONG64 *address,
|
||||
QString *errorMessage)
|
||||
@@ -90,7 +90,7 @@ static bool createDebuggeeAscIIString(IDebugControl4 *ctl,
|
||||
|
||||
// Locate 'qstrdup' in the (potentially namespaced) corelib. For some
|
||||
// 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;
|
||||
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"
|
||||
// as dummy symbol. This is ok ATM since dumpers only
|
||||
// make sense for Qt apps.
|
||||
static bool debuggeeLoadLibrary(IDebugControl4 *ctl,
|
||||
IDebugClient5 *client,
|
||||
IDebugSymbols3 *syms,
|
||||
IDebugDataSpaces4 *data,
|
||||
static bool debuggeeLoadLibrary(CIDebugControl *ctl,
|
||||
CIDebugClient *client,
|
||||
CIDebugSymbols *syms,
|
||||
CIDebugDataSpaces *data,
|
||||
const QString &moduleName, QString *errorMessage)
|
||||
{
|
||||
if (loadDebug)
|
||||
@@ -179,7 +179,7 @@ bool CdbDumperHelper::moduleLoadHook(const QString &name, bool *ignoreNextBreakP
|
||||
// Load once QtCore is there.
|
||||
if (name.contains(QLatin1String("QtCore"))) {
|
||||
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,
|
||||
m_library, &m_errorMessage);
|
||||
if (ok) {
|
||||
@@ -188,6 +188,8 @@ bool CdbDumperHelper::moduleLoadHook(const QString &name, bool *ignoreNextBreakP
|
||||
} else {
|
||||
m_state = Failed;
|
||||
}
|
||||
if (loadDebug)
|
||||
qDebug() << m_state << executionStatusString(m_cif->debugControl);
|
||||
}
|
||||
break;
|
||||
case Loading:
|
||||
|
@@ -36,7 +36,7 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorMessage)
|
||||
bool getModuleList(CIDebugSymbols *syms, QList<Module> *modules, QString *errorMessage)
|
||||
{
|
||||
modules->clear();
|
||||
ULONG loadedCount, unloadedCount;
|
||||
@@ -80,7 +80,7 @@ bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorM
|
||||
}
|
||||
|
||||
// Search symbols matching a pattern
|
||||
bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
||||
bool searchSymbols(CIDebugSymbols *syms, const QString &pattern,
|
||||
QStringList *matches, QString *errorMessage)
|
||||
{
|
||||
matches->clear();
|
||||
@@ -113,7 +113,7 @@ bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
||||
|
||||
// Add missing the module specifier: "main" -> "project!main"
|
||||
|
||||
ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol,
|
||||
ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol,
|
||||
QString *errorMessage)
|
||||
{
|
||||
// Is it an incomplete symbol?
|
||||
@@ -138,7 +138,7 @@ ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol,
|
||||
}
|
||||
|
||||
// List symbols of a module
|
||||
bool getModuleSymbols(IDebugSymbols3 *syms, const QString &moduleName,
|
||||
bool getModuleSymbols(CIDebugSymbols *syms, const QString &moduleName,
|
||||
QList<Symbol> *symbols, QString *errorMessage)
|
||||
{
|
||||
// Search all symbols and retrieve addresses
|
||||
|
@@ -33,8 +33,7 @@
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -42,9 +41,9 @@ namespace Internal {
|
||||
class Module;
|
||||
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
|
||||
bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
||||
bool searchSymbols(CIDebugSymbols *syms, const QString &pattern,
|
||||
QStringList *matches, QString *errorMessage);
|
||||
|
||||
// ResolveSymbol: For symbols that are missing the module specifier,
|
||||
@@ -53,10 +52,10 @@ bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
|
||||
enum ResolveSymbolResult { ResolveSymbolOk, ResolveSymbolAmbiguous,
|
||||
ResolveSymbolNotFound, ResolveSymbolError };
|
||||
|
||||
ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol, QString *errorMessage);
|
||||
ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol, QString *errorMessage);
|
||||
|
||||
// List symbols of a module
|
||||
bool getModuleSymbols(IDebugSymbols3 *syms, const QString &moduleName,
|
||||
bool getModuleSymbols(CIDebugSymbols *syms, const QString &moduleName,
|
||||
QList<Symbol> *symbols, QString *errorMessage);
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -33,27 +33,24 @@
|
||||
#include "cdbdebugengine_p.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
CdbStackTraceContext::CdbStackTraceContext(IDebugSystemObjects4* pDebugSystemObjects,
|
||||
IDebugSymbols3* pDebugSymbols) :
|
||||
m_pDebugSystemObjects(pDebugSystemObjects),
|
||||
m_pDebugSymbols(pDebugSymbols),
|
||||
CdbStackTraceContext::CdbStackTraceContext(CdbComInterfaces *cif) :
|
||||
m_cif(cif),
|
||||
m_instructionOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
CdbStackTraceContext *CdbStackTraceContext::create(IDebugControl4* pDebugControl,
|
||||
IDebugSystemObjects4* pDebugSystemObjects,
|
||||
IDebugSymbols3* pDebugSymbols,
|
||||
CdbStackTraceContext *CdbStackTraceContext::create(CdbComInterfaces *cif,
|
||||
unsigned long threadId,
|
||||
QString *errorMessage)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << threadId;
|
||||
HRESULT hr = pDebugSystemObjects->SetCurrentThreadId(threadId);
|
||||
HRESULT hr = cif->debugSystemObjects->SetCurrentThreadId(threadId);
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = QString::fromLatin1("%1: SetCurrentThreadId %2 failed: %3").
|
||||
arg(QString::fromLatin1(Q_FUNC_INFO)).
|
||||
@@ -63,8 +60,8 @@ CdbStackTraceContext *CdbStackTraceContext::create(IDebugControl4* pDebugControl
|
||||
}
|
||||
// fill the DEBUG_STACK_FRAME array
|
||||
ULONG frameCount;
|
||||
CdbStackTraceContext *ctx = new CdbStackTraceContext(pDebugSystemObjects, pDebugSymbols);
|
||||
hr = pDebugControl->GetStackTrace(0, 0, 0, ctx->m_cdbFrames, CdbStackTraceContext::maxFrames, &frameCount);
|
||||
CdbStackTraceContext *ctx = new CdbStackTraceContext(cif);
|
||||
hr = cif->debugControl->GetStackTrace(0, 0, 0, ctx->m_cdbFrames, CdbStackTraceContext::maxFrames, &frameCount);
|
||||
if (FAILED(hr)) {
|
||||
delete ctx;
|
||||
*errorMessage = msgComFailed("GetStackTrace", hr);
|
||||
@@ -100,12 +97,12 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
|
||||
m_instructionOffset = instructionOffset;
|
||||
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);
|
||||
|
||||
ULONG ulLine;
|
||||
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)) {
|
||||
frame.line = ulLine;
|
||||
// Vitally important to use canonical file that matches editormanager,
|
||||
@@ -131,7 +128,7 @@ CdbSymbolGroupContext *CdbStackTraceContext::symbolGroupContextAt(int index, QSt
|
||||
|
||||
if (m_symbolContexts.at(index))
|
||||
return m_symbolContexts.at(index);
|
||||
IDebugSymbolGroup2 *sg = createSymbolGroup(index, errorMessage);
|
||||
CIDebugSymbolGroup *sg = createSymbolGroup(index, errorMessage);
|
||||
if (!sg)
|
||||
return 0;
|
||||
CdbSymbolGroupContext *sc = CdbSymbolGroupContext::create(QLatin1String("local"), sg, errorMessage);
|
||||
@@ -141,23 +138,23 @@ CdbSymbolGroupContext *CdbStackTraceContext::symbolGroupContextAt(int index, QSt
|
||||
return sc;
|
||||
}
|
||||
|
||||
IDebugSymbolGroup2 *CdbStackTraceContext::createSymbolGroup(int index, QString *errorMessage)
|
||||
CIDebugSymbolGroup *CdbStackTraceContext::createSymbolGroup(int index, QString *errorMessage)
|
||||
{
|
||||
IDebugSymbolGroup2 *sg = 0;
|
||||
HRESULT hr = m_pDebugSymbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_LOCALS, NULL, &sg);
|
||||
CIDebugSymbolGroup *sg = 0;
|
||||
HRESULT hr = m_cif->debugSymbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_LOCALS, NULL, &sg);
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = msgComFailed("GetScopeSymbolGroup", hr);
|
||||
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)) {
|
||||
*errorMessage = msgComFailed("SetScope", hr);
|
||||
sg->Release();
|
||||
return 0;
|
||||
}
|
||||
// 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)) {
|
||||
*errorMessage = msgComFailed("GetScopeSymbolGroup", hr);
|
||||
sg->Release();
|
||||
@@ -166,5 +163,34 @@ IDebugSymbolGroup2 *CdbStackTraceContext::createSymbolGroup(int index, QString *
|
||||
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 Debugger
|
||||
|
@@ -32,15 +32,19 @@
|
||||
|
||||
#include "stackhandler.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextStream;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
struct CdbComInterfaces;
|
||||
class CdbSymbolGroupContext;
|
||||
|
||||
/* Context representing a break point stack consisting of several frames.
|
||||
@@ -51,15 +55,12 @@ class CdbStackTraceContext
|
||||
{
|
||||
Q_DISABLE_COPY(CdbStackTraceContext)
|
||||
|
||||
explicit CdbStackTraceContext(IDebugSystemObjects4* pDebugSystemObjects,
|
||||
IDebugSymbols3* pDebugSymbols);
|
||||
explicit CdbStackTraceContext(CdbComInterfaces *cif);
|
||||
public:
|
||||
enum { maxFrames = 100 };
|
||||
|
||||
~CdbStackTraceContext();
|
||||
static CdbStackTraceContext *create(IDebugControl4* pDebugControl,
|
||||
IDebugSystemObjects4* pDebugSystemObjects,
|
||||
IDebugSymbols3* pDebugSymbols,
|
||||
static CdbStackTraceContext *create(CdbComInterfaces *cif,
|
||||
unsigned long threadid,
|
||||
QString *errorMessage);
|
||||
|
||||
@@ -71,12 +72,15 @@ public:
|
||||
|
||||
CdbSymbolGroupContext *symbolGroupContextAt(int index, QString *errorMessage);
|
||||
|
||||
// Format for logging
|
||||
void format(QTextStream &str) const;
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
bool init(unsigned long frameCount, QString *errorMessage);
|
||||
IDebugSymbolGroup2 *createSymbolGroup(int index, QString *errorMessage);
|
||||
CIDebugSymbolGroup *createSymbolGroup(int index, QString *errorMessage);
|
||||
|
||||
IDebugSystemObjects4* m_pDebugSystemObjects;
|
||||
IDebugSymbols3* m_pDebugSymbols;
|
||||
CdbComInterfaces *m_cif;
|
||||
|
||||
DEBUG_STACK_FRAME m_cdbFrames[maxFrames];
|
||||
QVector <CdbSymbolGroupContext*> m_symbolContexts;
|
||||
|
@@ -105,7 +105,7 @@ static inline CdbSymbolGroupContext::SymbolState getSymbolState(const DEBUG_SYMB
|
||||
}
|
||||
|
||||
CdbSymbolGroupContext::CdbSymbolGroupContext(const QString &prefix,
|
||||
IDebugSymbolGroup2 *symbolGroup) :
|
||||
CIDebugSymbolGroup *symbolGroup) :
|
||||
m_prefix(prefix),
|
||||
m_nameDelimiter(QLatin1Char('.')),
|
||||
m_symbolGroup(symbolGroup)
|
||||
@@ -118,7 +118,7 @@ CdbSymbolGroupContext::~CdbSymbolGroupContext()
|
||||
}
|
||||
|
||||
CdbSymbolGroupContext *CdbSymbolGroupContext::create(const QString &prefix,
|
||||
IDebugSymbolGroup2 *symbolGroup,
|
||||
CIDebugSymbolGroup *symbolGroup,
|
||||
QString *errorMessage)
|
||||
{
|
||||
CdbSymbolGroupContext *rc= new CdbSymbolGroupContext(prefix, symbolGroup);
|
||||
@@ -343,7 +343,7 @@ QString CdbSymbolGroupContext::symbolINameAt(unsigned long index) const
|
||||
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;
|
||||
if (FAILED(sg->GetSymbolOffset(index, &rc)))
|
||||
@@ -436,7 +436,7 @@ template <class Integer>
|
||||
return rc;
|
||||
}
|
||||
|
||||
QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl,
|
||||
QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, CIDebugControl *ctl,
|
||||
QString *qType,
|
||||
int integerBase)
|
||||
{
|
||||
|
@@ -30,8 +30,7 @@
|
||||
#ifndef CDBSYMBOLGROUPCONTEXT_H
|
||||
#define CDBSYMBOLGROUPCONTEXT_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
#include "cdbcom.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
@@ -60,12 +59,12 @@ class CdbSymbolGroupContext
|
||||
{
|
||||
Q_DISABLE_COPY(CdbSymbolGroupContext);
|
||||
explicit CdbSymbolGroupContext(const QString &prefix,
|
||||
IDebugSymbolGroup2 *symbolGroup);
|
||||
CIDebugSymbolGroup *symbolGroup);
|
||||
|
||||
public:
|
||||
~CdbSymbolGroupContext();
|
||||
static CdbSymbolGroupContext *create(const QString &prefix,
|
||||
IDebugSymbolGroup2 *symbolGroup,
|
||||
CIDebugSymbolGroup *symbolGroup,
|
||||
QString *errorMessage);
|
||||
|
||||
QString prefix() const { return m_prefix; }
|
||||
@@ -92,7 +91,7 @@ public:
|
||||
inline bool isExpanded(const QString &prefix) const { return symbolState(prefix) == ExpandedSymbol; }
|
||||
|
||||
// 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, ..."
|
||||
static QString hexFormatArray(const unsigned short *array, int size);
|
||||
@@ -121,7 +120,7 @@ private:
|
||||
const QString m_prefix;
|
||||
const QChar m_nameDelimiter;
|
||||
|
||||
IDebugSymbolGroup2 *m_symbolGroup;
|
||||
CIDebugSymbolGroup *m_symbolGroup;
|
||||
NameIndexMap m_inameIndexMap;
|
||||
QVector<DEBUG_SYMBOL_PARAMETERS> m_symbolParameters;
|
||||
};
|
||||
|
@@ -8,6 +8,8 @@ include(../../qworkbenchlibrary.pri)
|
||||
linux-* {
|
||||
CONFIG -= release
|
||||
CONFIG += debug
|
||||
# The following line works around a linker issue with gcc 4.1.2
|
||||
QMAKE_CXXFLAGS *= -O2
|
||||
}
|
||||
|
||||
SOURCES += ../../../share/qtcreator/gdbmacros/gdbmacros.cpp
|
||||
|
@@ -3173,7 +3173,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
||||
sendWatchParameters(params);
|
||||
|
||||
QString cmd ="call "
|
||||
+ QString("qDumpObjectData440(")
|
||||
+ QString("(void*)qDumpObjectData440(")
|
||||
+ QString::number(protocol)
|
||||
+ ',' + "%1+1" // placeholder for token
|
||||
+ ',' + addr
|
||||
@@ -3469,7 +3469,7 @@ void GdbEngine::sendWatchParameters(const QByteArray ¶ms0)
|
||||
QByteArray params = params0;
|
||||
params.append('\0');
|
||||
char buf[50];
|
||||
sprintf(buf, "set {char[%d]} qDumpInBuffer = {", params.size());
|
||||
sprintf(buf, "set {char[%d]} &qDumpInBuffer = {", params.size());
|
||||
QByteArray encoded;
|
||||
encoded.append(buf);
|
||||
for (int i = 0; i != params.size(); ++i) {
|
||||
@@ -4177,14 +4177,14 @@ void GdbEngine::tryLoadDebuggingHelpers()
|
||||
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||
#endif
|
||||
// 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);
|
||||
}
|
||||
|
||||
void GdbEngine::recheckDebuggingHelperAvailability()
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@@ -1554,7 +1554,7 @@ void ProjectExplorerPlugin::updateRecentProjectMenu()
|
||||
const QPair<QString, QString> &s = *it;
|
||||
if (s.first.endsWith(".qws"))
|
||||
continue;
|
||||
QAction *action = menu->addAction(s.second);
|
||||
QAction *action = menu->addAction(s.first);
|
||||
action->setData(s.first);
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
|
||||
}
|
||||
|
Reference in New Issue
Block a user