From e82d6c7b057b012b417c3493e0493dbb1b59e0c2 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Fri, 14 Aug 2009 13:04:05 +0200
Subject: [PATCH] debugger: create a disassembler view as main editor

"Stepping instruction wise" and "display disassembler" mode is now toggled by a
single action. This also allows to re-use F10 and F11 as keyboard shortcut.

Missing: caching of disassembler output, removal of old disassembler view.
---
 src/plugins/debugger/breakhandler.cpp        |  20 +-
 src/plugins/debugger/breakhandler.h          |  10 +-
 src/plugins/debugger/cdb/cdbdebugengine.cpp  |   2 +-
 src/plugins/debugger/cpptools.cpp            |  47 +++++
 src/plugins/debugger/cpptools.h              |  44 +++++
 src/plugins/debugger/debuggeractions.cpp     |   7 +
 src/plugins/debugger/debuggeractions.h       |   1 +
 src/plugins/debugger/debuggeragents.cpp      | 158 ++++++++++++++-
 src/plugins/debugger/debuggeragents.h        |  35 +++-
 src/plugins/debugger/debuggerconstants.h     |   2 -
 src/plugins/debugger/debuggermanager.cpp     |  98 +++++-----
 src/plugins/debugger/debuggermanager.h       |  17 +-
 src/plugins/debugger/debuggerplugin.cpp      |  70 +++----
 src/plugins/debugger/debuggerplugin.h        |  10 +-
 src/plugins/debugger/debuggertooltip.h       |   2 +-
 src/plugins/debugger/gdb/gdbengine.cpp       | 195 ++++++++++++++++---
 src/plugins/debugger/gdb/gdbengine.h         |  11 ++
 src/plugins/debugger/idebuggerengine.h       |   8 +-
 src/plugins/debugger/registerhandler.cpp     |   6 +
 src/plugins/debugger/registerwindow.cpp      |  19 +-
 src/plugins/debugger/registerwindow.h        |   6 +-
 src/plugins/debugger/script/scriptengine.cpp |   5 +-
 src/plugins/debugger/stackframe.h            |  60 ++++++
 src/plugins/debugger/stackhandler.cpp        |  30 ++-
 src/plugins/debugger/stackhandler.h          |  18 +-
 src/plugins/debugger/stackwindow.cpp         |  67 +++++--
 src/plugins/debugger/stackwindow.h           |   7 +-
 src/plugins/debugger/watchwindow.cpp         |  11 +-
 28 files changed, 757 insertions(+), 209 deletions(-)
 create mode 100644 src/plugins/debugger/cpptools.cpp
 create mode 100644 src/plugins/debugger/cpptools.h
 create mode 100644 src/plugins/debugger/stackframe.h

diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 7f333077c9d..ee6f75196d1 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -29,6 +29,9 @@
 
 #include "breakhandler.h"
 
+#include "debuggermanager.h"
+#include "stackframe.h"
+
 #include "imports.h" // TextEditor::BaseTextMark
 
 #include <QtCore/QDebug>
@@ -242,8 +245,8 @@ bool BreakpointData::conditionsMatch() const
 //
 //////////////////////////////////////////////////////////////////
 
-BreakHandler::BreakHandler(QObject *parent)
-    : QAbstractItemModel(parent)
+BreakHandler::BreakHandler(DebuggerManager *manager, QObject *parent)
+    : QAbstractItemModel(parent), m_manager(manager)
 {
 }
 
@@ -345,13 +348,12 @@ void BreakHandler::saveBreakpoints()
             map.insert(QLatin1String("usefullpath"), QLatin1String("1"));
         list.append(map);
     }
-    setSessionValueRequested("Breakpoints", list);
+    m_manager->setSessionValue("Breakpoints", list);
 }
 
 void BreakHandler::loadBreakpoints()
 {
-    QVariant value;
-    sessionValueRequested("Breakpoints", &value);
+    QVariant value = m_manager->sessionValue("Breakpoints");
     QList<QVariant> list = value.toList();
     clear();
     foreach (const QVariant &var, list) {
@@ -677,8 +679,12 @@ void BreakHandler::activateBreakpoint(int index)
 {
     const BreakpointData *data = at(index);
     //qDebug() << "BREAKPOINT ACTIVATED: " << data->fileName;
-    if (!data->markerFileName.isEmpty())
-        emit gotoLocation(data->markerFileName, data->markerLineNumber, false);
+    if (!data->markerFileName.isEmpty()) {
+        StackFrame frame;
+        frame.file = data->markerFileName;
+        frame.line = data->markerLineNumber;
+        m_manager->gotoLocation(frame, false);
+    }
 }
 
 void BreakHandler::breakByFunction(const QString &functionName)
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index 77c96f20eee..d02800625ca 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -40,6 +40,7 @@ namespace Internal {
 
 class BreakpointMarker;
 class BreakHandler;
+class DebuggerManager;
 
 //////////////////////////////////////////////////////////////////
 //
@@ -113,7 +114,7 @@ class BreakHandler : public QAbstractItemModel
     Q_OBJECT
 
 public:
-    explicit BreakHandler(QObject *parent = 0);
+    explicit BreakHandler(DebuggerManager *manager, QObject *parent = 0);
     ~BreakHandler();
 
     void removeAllBreakpoints();
@@ -149,12 +150,6 @@ public slots:
     void activateBreakpoint(int index);
     void removeBreakpoint(int index);
 
-signals:
-    void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
-
-    void sessionValueRequested(const QString &name, QVariant *value);
-    void setSessionValueRequested(const QString &name, const QVariant &value);
-
 private:
     friend class BreakpointMarker;
 
@@ -175,6 +170,7 @@ private:
     void resetBreakpoints();
     void removeBreakpointHelper(int index);
 
+    DebuggerManager *m_manager; // not owned
     QList<BreakpointData *> m_bp;
     QList<BreakpointData *> m_inserted; // lately inserted breakpoints
     QList<BreakpointData *> m_removed; // lately removed breakpoints
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index c0732065937..51af8db4b70 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -1178,7 +1178,7 @@ void CdbDebugEngine::activateFrame(int frameIndex)
             break;
         }
 
-        m_d->m_debuggerManager->gotoLocation(frame.file, frame.line, true);
+        m_d->m_debuggerManager->gotoLocation(frame, true);
 
         if (oldIndex != frameIndex || m_d->m_firstActivatedFrame) {
             watchHandler->beginCycle();
diff --git a/src/plugins/debugger/cpptools.cpp b/src/plugins/debugger/cpptools.cpp
new file mode 100644
index 00000000000..9b38e4615eb
--- /dev/null
+++ b/src/plugins/debugger/cpptools.cpp
@@ -0,0 +1,47 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "cpptools.h"
+
+namespace Debugger {
+namespace Internal {
+
+QByteArray mangleName(const QByteArray &ba)
+{
+    return ba;
+}
+
+
+QByteArray demangleName(const QByteArray &ba)
+{
+    return ba;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cpptools.h b/src/plugins/debugger/cpptools.h
new file mode 100644
index 00000000000..e056d07cd45
--- /dev/null
+++ b/src/plugins/debugger/cpptools.h
@@ -0,0 +1,44 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_CPPTOOLS_H
+#define DEBUGGER_CPPTOOLS_H
+
+#include <QtCore/QByteArray>
+
+namespace Debugger {
+namespace Internal {
+
+QByteArray mangleName(const QByteArray &ba);
+QByteArray demangleName(const QByteArray &ba);
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_WATCHWINDOW_H
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index 6c8f60bcb15..6b86696c0a5 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -151,6 +151,13 @@ DebuggerSettings *DebuggerSettings::instance()
     item->setDefaultValue(false);
     instance->insertItem(LogTimeStamps, item);
 
+    item = new SavedAction(instance);
+    item->setText(tr("Step by instruction"));
+    item->setCheckable(true);
+    item->setDefaultValue(false);
+    item->setIcon(QIcon(":/debugger/images/debugger_stepoverproc_small.png"));
+    instance->insertItem(StepByInstruction, item);
+
     //
     // Locals & Watchers
     //
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index a929d2e8ccf..6d9656ffce0 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -77,6 +77,7 @@ enum DebuggerActionCode
     AutoQuit,
     LockView,
     LogTimeStamps,
+    StepByInstruction,
 
     RecheckDebuggingHelpers,
     UseDebuggingHelpers,
diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp
index 3f6550f1d76..8e5e5bc1125 100644
--- a/src/plugins/debugger/debuggeragents.cpp
+++ b/src/plugins/debugger/debuggeragents.cpp
@@ -30,15 +30,59 @@
 #include "debuggeragents.h"
 #include "idebuggerengine.h"
 
+#include <coreplugin/coreconstants.h>
 #include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
+#include <coreplugin/icore.h>
+
+#include <texteditor/basetexteditor.h>
+#include <texteditor/basetextmark.h>
+#include <texteditor/itexteditor.h>
+#include <texteditor/texteditorconstants.h>
+
+#include <utils/qtcassert.h>
+
+#include <QtGui/QPlainTextEdit>
+#include <QtGui/QTextCursor>
 
 #include <limits.h>
 
 namespace Debugger {
 namespace Internal {
 
+///////////////////////////////////////////////////////////////////////
+//
+// MemoryViewAgent
+//
+///////////////////////////////////////////////////////////////////////
+
+/*! 
+    \class MemoryViewAgent
+
+    Objects form this class are created in response to user actions in
+    the Gui for showing raw memory from the inferior. After creation
+    it handles communication between the engine and the bineditor.
+*/
+
 MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
     : QObject(manager), m_engine(manager->currentEngine())
+{
+    init(addr);
+}
+
+MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
+    : QObject(manager), m_engine(manager->currentEngine())
+{
+    bool ok = true;
+    init(addr.toUInt(&ok, 0));
+}
+
+MemoryViewAgent::~MemoryViewAgent()
+{
+    m_editor->deleteLater();
+}
+
+void MemoryViewAgent::init(quint64 addr) 
 {
     Core::EditorManager *editorManager = Core::EditorManager::instance();
     QString titlePattern = "Memory $";
@@ -49,12 +93,7 @@ MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
         this, SLOT(fetchLazyData(int,bool)));
     editorManager->activateEditor(m_editor);
     QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
-    Q_ARG(int, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize));
-}
-
-MemoryViewAgent::~MemoryViewAgent()
-{
-    m_editor->deleteLater();
+        Q_ARG(int, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize));
 }
 
 void MemoryViewAgent::fetchLazyData(int block, bool sync)
@@ -70,6 +109,113 @@ void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
 }
 
 
+///////////////////////////////////////////////////////////////////////
+//
+// DisassemblerViewAgent
+//
+///////////////////////////////////////////////////////////////////////
+
+static QIcon locationMarkIcon()
+{
+    static const QIcon icon(":/debugger/images/location.svg");
+    return icon;
+}
+
+// Used for the disassembler view
+class LocationMark2 : public TextEditor::ITextMark
+{
+public:
+    LocationMark2() {}
+
+    QIcon icon() const { return locationMarkIcon(); }
+    void updateLineNumber(int /*lineNumber*/) {}
+    void updateBlock(const QTextBlock & /*block*/) {}
+    void removedFromEditor() {}
+    void documentClosing() {}
+};
+
+struct DisassemblerViewAgentPrivate
+{
+    QPointer<TextEditor::ITextEditor> editor;
+    QPointer<IDebuggerEngine> engine;
+    QString address;
+    LocationMark2 *locationMark;
+};
+
+/*!
+    \class DisassemblerViewAgent
+
+     Objects from this class are created in response to user actions in
+     the Gui for showing disassembled memory from the inferior. After creation
+     it handles communication between the engine and the editor.
+*/
+
+DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager)
+    : QObject(manager), d(new DisassemblerViewAgentPrivate)
+{
+    d->editor = 0;
+    d->engine = manager->currentEngine();
+    d->locationMark = new LocationMark2();
+}
+
+DisassemblerViewAgent::~DisassemblerViewAgent()
+{
+    if (d->editor)
+        d->editor->deleteLater();
+    delete d;
+}
+
+void DisassemblerViewAgent::setFrame(const StackFrame &frame)
+{
+    d->engine->fetchDisassembler(this, frame);
+    d->address = frame.address;
+}
+
+void DisassemblerViewAgent::setContents(const QString &contents)
+{
+    using namespace Core;
+    using namespace TextEditor;
+
+    EditorManager *editorManager = EditorManager::instance();
+    if (!d->editor) {
+        QString titlePattern = "Disassembler";
+        d->editor = qobject_cast<ITextEditor *>(
+            editorManager->openEditorWithContents(
+            Core::Constants::K_DEFAULT_TEXT_EDITOR,
+            &titlePattern));
+    }
+
+    editorManager->activateEditor(d->editor);
+
+    QPlainTextEdit *plainTextEdit =
+        qobject_cast<QPlainTextEdit *>(d->editor->widget());
+    if (plainTextEdit)
+        plainTextEdit->setPlainText(contents);
+
+    d->editor->markableInterface()->removeMark(d->locationMark);
+
+    for (int pos = 0, line = 0; ; ++line, ++pos) {
+        if (contents.midRef(pos, d->address.size()) == d->address) {
+            d->editor->markableInterface()->addMark(d->locationMark, line + 1);
+            if (plainTextEdit) {
+                QTextCursor tc = plainTextEdit->textCursor();
+                tc.setPosition(pos);
+                plainTextEdit->setTextCursor(tc);
+            }
+            break;
+        }
+        pos = contents.indexOf('\n', pos + 1);
+        if (pos == -1)
+            break;
+    }
+}
+
+QString DisassemblerViewAgent::address() const
+{
+    return d->address;
+}
+
 } // namespace Internal
 } // namespace Debugger
 
+#include "debuggeragents.moc"
diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h
index f9984b84933..b48eb703af6 100644
--- a/src/plugins/debugger/debuggeragents.h
+++ b/src/plugins/debugger/debuggeragents.h
@@ -31,26 +31,21 @@
 #define DEBUGGER_AGENTS_H
 
 #include "debuggermanager.h"
+#include "stackframe.h"
 
-#include <coreplugin/icore.h>
-#include <coreplugin/coreconstants.h>
 #include <coreplugin/editormanager/ieditor.h>
 
-#include <utils/qtcassert.h>
-
 #include <QtCore/QObject>
 #include <QtCore/QDebug>
 #include <QtCore/QPointer>
 #include <QtGui/QAction>
 
+
 namespace Debugger {
 namespace Internal {
 
 class DebuggerManager;
-
-// Object form this class are created in response to user actions in
-// the Gui for showing raw memory from the inferior. After creation
-// it handles communication between the engine and the bineditor.
+class DisassemblerViewAgentPrivate;
 
 class MemoryViewAgent : public QObject
 {
@@ -59,6 +54,7 @@ class MemoryViewAgent : public QObject
 public:
     // Called from Gui
     MemoryViewAgent(DebuggerManager *manager, quint64 startaddr);
+    MemoryViewAgent(DebuggerManager *manager, const QString &startaddr);
     ~MemoryViewAgent();
 
     enum { BinBlockSize = 1024 };
@@ -69,11 +65,32 @@ public slots:
     // Called from Editor
     void fetchLazyData(int block, bool sync);
 
-public:
+private:
+    void init(quint64 startaddr);
+
     QPointer<IDebuggerEngine> m_engine;
     QPointer<Core::IEditor> m_editor;
 };
 
+
+class DisassemblerViewAgent : public QObject
+{
+    Q_OBJECT
+
+public:
+    // Called from Gui
+    DisassemblerViewAgent(DebuggerManager *manager);
+    ~DisassemblerViewAgent();
+
+    void setFrame(const StackFrame &frame);
+    Q_SLOT void setContents(const QString &contents);
+    QString address() const;
+
+private:
+    DisassemblerViewAgentPrivate *d;
+};
+
+
 } // namespace Internal
 } // namespace Debugger
 
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index 0ff77414952..337ab8ba342 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -45,8 +45,6 @@ const char * const RESET                = "Debugger.Reset";
 const char * const STEP                 = "Debugger.StepLine";
 const char * const STEPOUT              = "Debugger.StepOut";
 const char * const NEXT                 = "Debugger.NextLine";
-const char * const STEPI                = "Debugger.StepInstruction";
-const char * const NEXTI                = "Debugger.NextInstruction";
 const char * const REVERSE              = "Debugger.ReverseDirection";
 
 const char * const M_DEBUG_VIEWS        = "Debugger.Menu.View.Debug";
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 6d81c5ecdd0..76b253726be 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -219,8 +219,8 @@ void DebuggerManager::init()
     m_disassemblerWindow = new DisassemblerWindow;
     m_modulesWindow = new ModulesWindow(this);
     m_outputWindow = new DebuggerOutputWindow;
-    m_registerWindow = new RegisterWindow;
-    m_stackWindow = new StackWindow;
+    m_registerWindow = new RegisterWindow(this);
+    m_stackWindow = new StackWindow(this);
     m_sourceFilesWindow = new SourceFilesWindow;
     m_threadsWindow = new ThreadsWindow;
     m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this);
@@ -261,7 +261,7 @@ void DebuggerManager::init()
             this, SLOT(reloadDisassembler()));
 
     // Breakpoints
-    m_breakHandler = new BreakHandler;
+    m_breakHandler = new BreakHandler(this);
     QAbstractItemView *breakView =
         qobject_cast<QAbstractItemView *>(m_breakWindow);
     breakView->setModel(m_breakHandler->model());
@@ -271,12 +271,6 @@ void DebuggerManager::init()
         m_breakHandler, SLOT(removeBreakpoint(int)));
     connect(breakView, SIGNAL(breakpointSynchronizationRequested()),
         this, SLOT(attemptBreakpointSynchronization()));
-    connect(m_breakHandler, SIGNAL(gotoLocation(QString,int,bool)),
-        this, SLOT(gotoLocation(QString,int,bool)));
-    connect(m_breakHandler, SIGNAL(sessionValueRequested(QString,QVariant*)),
-        this, SIGNAL(sessionValueRequested(QString,QVariant*)));
-    connect(m_breakHandler, SIGNAL(setSessionValueRequested(QString,QVariant)),
-        this, SIGNAL(setSessionValueRequested(QString,QVariant)));
     connect(breakView, SIGNAL(breakByFunctionRequested(QString)),
         this, SLOT(breakByFunction(QString)), Qt::QueuedConnection);
     connect(breakView, SIGNAL(breakByFunctionMainRequested()),
@@ -357,16 +351,6 @@ void DebuggerManager::init()
     //m_stepAction->setShortcut(QKeySequence(tr("F7")));
     m_stepAction->setIcon(QIcon(":/debugger/images/debugger_stepinto_small.png"));
 
-    m_nextIAction = new QAction(this);
-    m_nextIAction->setText(tr("Step Over Instruction"));
-    //m_nextIAction->setShortcut(QKeySequence(tr("Shift+F6")));
-    m_nextIAction->setIcon(QIcon(":/debugger/images/debugger_stepoverproc_small.png"));
-
-    m_stepIAction = new QAction(this);
-    m_stepIAction->setText(tr("Step One Instruction"));
-    //m_stepIAction->setShortcut(QKeySequence(tr("Shift+F9")));
-    m_stepIAction->setIcon(QIcon(":/debugger/images/debugger_steponeproc_small.png"));
-
     m_stepOutAction = new QAction(this);
     m_stepOutAction->setText(tr("Step Out"));
     //m_stepOutAction->setShortcut(QKeySequence(tr("Shift+F7")));
@@ -405,10 +389,8 @@ void DebuggerManager::init()
         this, SLOT(nextExec()));
     connect(m_stepAction, SIGNAL(triggered()),
         this, SLOT(stepExec()));
-    connect(m_nextIAction, SIGNAL(triggered()),
-        this, SLOT(nextIExec()));
-    connect(m_stepIAction, SIGNAL(triggered()),
-        this, SLOT(stepIExec()));
+    connect(theDebuggerAction(StepByInstruction), SIGNAL(triggered()),
+        this, SLOT(stepByInstructionTriggered()));
     connect(m_stepOutAction, SIGNAL(triggered()),
         this, SLOT(stepOutExec()));
     connect(m_runToLineAction, SIGNAL(triggered()),
@@ -427,9 +409,14 @@ void DebuggerManager::init()
 
     connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
         this, SLOT(executeDebuggerCommand()));
+
     connect(theDebuggerAction(WatchPoint), SIGNAL(triggered()),
         this, SLOT(watchPoint()));
 
+    connect(theDebuggerAction(StepByInstruction), SIGNAL(triggered()),
+        this, SLOT(stepByInstructionTriggered()));
+
+
     m_breakDock = m_mainWindow->addDockForWidget(m_breakWindow);
 
     m_disassemblerDock = m_mainWindow->addDockForWidget(m_disassemblerWindow);
@@ -725,14 +712,6 @@ void DebuggerManager::updateWatchData(const WatchData &data)
         m_engine->updateWatchData(data);
 }
 
-QVariant DebuggerManager::sessionValue(const QString &name)
-{
-    // this is answered by the plugin
-    QVariant value;
-    emit sessionValueRequested(name, &value);
-    return value;
-}
-
 static inline QString msgEngineNotAvailable(const char *engine)
 {
     return DebuggerManager::tr("The application requires the debugger engine '%1', which is disabled.").arg(QLatin1String(engine));
@@ -986,7 +965,10 @@ void DebuggerManager::stepExec()
 {
     QTC_ASSERT(m_engine, return);
     resetLocation();
-    m_engine->stepExec();
+    if (theDebuggerBoolSetting(StepByInstruction))
+        m_engine->stepIExec();
+    else
+        m_engine->stepExec();
 }
 
 void DebuggerManager::stepOutExec()
@@ -1000,21 +982,10 @@ void DebuggerManager::nextExec()
 {
     QTC_ASSERT(m_engine, return);
     resetLocation();
-    m_engine->nextExec();
-}
-
-void DebuggerManager::stepIExec()
-{
-    QTC_ASSERT(m_engine, return);
-    resetLocation();
-    m_engine->stepIExec();
-}
-
-void DebuggerManager::nextIExec()
-{
-    QTC_ASSERT(m_engine, return);
-    resetLocation();
-    m_engine->nextIExec();
+    if (theDebuggerBoolSetting(StepByInstruction))
+        m_engine->nextIExec();
+    else
+        m_engine->nextExec();
 }
 
 void DebuggerManager::watchPoint()
@@ -1190,8 +1161,6 @@ void DebuggerManager::setStatus(int status)
     m_runToFunctionAction->setEnabled(ready);
     m_jumpToLineAction->setEnabled(ready);
     m_nextAction->setEnabled(ready);
-    m_stepIAction->setEnabled(ready);
-    m_nextIAction->setEnabled(ready);
     //showStatusMessage(QString("started: %1, running: %2").arg(started).arg(running));
     emit statusChanged(m_status);
     const bool notbusy = ready || status == DebuggerProcessNotReady;
@@ -1316,17 +1285,26 @@ void DebuggerManager::resetLocation()
     emit resetLocationRequested();
 }
 
-void DebuggerManager::gotoLocation(const QString &fileName, int line,
-    bool setMarker)
+void DebuggerManager::gotoLocation(const StackFrame &frame, bool setMarker)
 {
     // connected to the plugin
-    emit gotoLocationRequested(fileName, line, setMarker);
+    emit gotoLocationRequested(frame, setMarker);
 }
 
 void DebuggerManager::fileOpen(const QString &fileName)
 {
     // connected to the plugin
-    emit gotoLocationRequested(fileName, 1, false);
+    StackFrame frame;
+    frame.file = fileName;
+    frame.line = -1;
+    emit gotoLocationRequested(frame, false);
+}
+
+void DebuggerManager::stepByInstructionTriggered()
+{
+    QTC_ASSERT(m_stackHandler, return);
+    StackFrame frame = m_stackHandler->currentFrame();
+    gotoLocation(frame, true);
 }
 
 
@@ -1497,6 +1475,20 @@ bool DebuggerManager::isReverseDebugging() const
     return m_reverseDirectionAction->isChecked();
 }
 
+QVariant DebuggerManager::sessionValue(const QString &name)
+{
+    // this is answered by the plugin
+    QVariant value;
+    emit sessionValueRequested(name, &value);
+    return value;
+}
+
+void DebuggerManager::setSessionValue(const QString &name, const QVariant &value)
+{
+    emit setSessionValueRequested(name, value);
+}
+
+
 //////////////////////////////////////////////////////////////////////
 //
 // Testing
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 65aa96f8099..8bf7e2a3aef 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -77,6 +77,7 @@ class DisassemblerHandler;
 class ModulesHandler;
 class RegisterHandler;
 class SourceFilesWindow;
+class StackFrame;
 class StackHandler;
 class Symbol;
 class ThreadsHandler;
@@ -141,8 +142,9 @@ enum LogChannel
     LogMisc    
 };
 
-struct DebuggerStartParameters
+class DebuggerStartParameters
 {
+public:
     DebuggerStartParameters();
     void clear();
 
@@ -281,9 +283,8 @@ public slots:
 
     void setBusyCursor(bool on);
     void queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **ed);
-    QVariant sessionValue(const QString &name);
 
-    void gotoLocation(const QString &file, int line, bool setLocationMarker);
+    void gotoLocation(const StackFrame &frame, bool setLocationMarker);
     void fileOpen(const QString &file);
     void resetLocation();
 
@@ -302,8 +303,6 @@ public slots:
     void stepExec();
     void stepOutExec();
     void nextExec();
-    void stepIExec();
-    void nextIExec();
     void continueExec();
     void detachDebugger();
 
@@ -313,6 +312,8 @@ public slots:
     void sessionLoaded();
     void aboutToUnloadSession();
     void aboutToSaveSession();
+    QVariant sessionValue(const QString &name);
+    void setSessionValue(const QString &name, const QVariant &value);
 
     void assignValueInDebugger();
     void assignValueInDebugger(const QString &expr, const QString &value);
@@ -346,6 +347,7 @@ private slots:
     void clearStatusMessage();
     void attemptBreakpointSynchronization();
     void reloadFullStack();
+    void stepByInstructionTriggered();
 
 private:
     //
@@ -404,7 +406,7 @@ signals:
     void debugModeRequested();
     void previousModeRequested();
     void statusMessageRequested(const QString &msg, int timeout); // -1 for 'forever'
-    void gotoLocationRequested(const QString &file, int line, bool setLocationMarker);
+    void gotoLocationRequested(const StackFrame &frame, bool setLocationMarker);
     void resetLocationRequested();
     void currentTextEditorRequested(QString *fileName, int *lineNumber, QObject **ob);
     void sessionValueRequested(const QString &name, QVariant *value);
@@ -468,8 +470,7 @@ private:
     QAction *m_watchAction;
     QAction *m_breakAction;
     QAction *m_sepAction;
-    QAction *m_stepIAction;
-    QAction *m_nextIAction;
+    //QActio *m_stepByInstructionAction;
     QAction *m_reverseDirectionAction;
 
     QWidget *m_breakWindow;
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 93f660b21b5..475f566aff5 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -31,10 +31,12 @@
 
 #include "breakhandler.h"
 #include "debuggeractions.h"
+#include "debuggeragents.h"
 #include "debuggerdialogs.h"
 #include "debuggerconstants.h"
 #include "debuggermanager.h"
 #include "debuggerrunner.h"
+#include "stackframe.h"
 
 #include "ui_commonoptionspage.h"
 #include "ui_dumperoptionpage.h"
@@ -116,6 +118,7 @@ const char * const TOGGLE_BREAK         = "Debugger.ToggleBreak";
 const char * const BREAK_BY_FUNCTION    = "Debugger.BreakByFunction";
 const char * const BREAK_AT_MAIN        = "Debugger.BreakAtMain";
 const char * const ADD_TO_WATCH         = "Debugger.AddToWatch";
+const char * const STEP_BY_INSTRUCTION  = "Debugger.StepByInstruction";
 
 #ifdef Q_WS_MAC
 const char * const INTERRUPT_KEY            = "Shift+F5";
@@ -123,8 +126,6 @@ const char * const RESET_KEY                = "Ctrl+Shift+F5";
 const char * const STEP_KEY                 = "F7";
 const char * const STEPOUT_KEY              = "Shift+F7";
 const char * const NEXT_KEY                 = "F6";
-const char * const STEPI_KEY                = "Shift+F9";
-const char * const NEXTI_KEY                = "Shift+F6";
 const char * const REVERSE_KEY              = "";
 const char * const RUN_TO_LINE_KEY          = "Shift+F8";
 const char * const RUN_TO_FUNCTION_KEY      = "Ctrl+F6";
@@ -139,8 +140,6 @@ const char * const RESET_KEY                = "Ctrl+Shift+F5";
 const char * const STEP_KEY                 = "F11";
 const char * const STEPOUT_KEY              = "Shift+F11";
 const char * const NEXT_KEY                 = "F10";
-const char * const STEPI_KEY                = "";
-const char * const NEXTI_KEY                = "";
 const char * const REVERSE_KEY              = "F12";
 const char * const RUN_TO_LINE_KEY          = "";
 const char * const RUN_TO_FUNCTION_KEY      = "";
@@ -218,6 +217,13 @@ DebugMode::~DebugMode()
 namespace Debugger {
 namespace Internal {
 
+static QIcon locationMarkIcon()
+{
+    static const QIcon icon(":/debugger/images/location.svg");
+    return icon;
+}
+
+// Used in "real" editors
 class LocationMark : public TextEditor::BaseTextMark
 {
     Q_OBJECT
@@ -226,25 +232,13 @@ public:
     LocationMark(const QString &fileName, int linenumber)
         : BaseTextMark(fileName, linenumber)
     {}
-    ~LocationMark();
 
-    QIcon icon() const;
+    QIcon icon() const { return locationMarkIcon(); }
     void updateLineNumber(int /*lineNumber*/) {}
     void updateBlock(const QTextBlock & /*block*/) {}
     void removedFromEditor() {}
 };
 
-LocationMark::~LocationMark()
-{
-    //qDebug() << "LOCATIONMARK DESTRUCTOR";
-}
-
-QIcon LocationMark::icon() const
-{
-    static const QIcon icon(":/debugger/images/location.svg");
-    return icon;
-}
-
 } // namespace Internal
 } // namespace Debugger
 
@@ -422,6 +416,7 @@ DebuggerPlugin::DebuggerPlugin()
   : m_manager(0),
     m_debugMode(0),
     m_locationMark(0),
+    m_disassemblerViewAgent(0),
     m_gdbRunningContext(0),
     m_cmdLineEnabledEngines(AllEngineTypes),
     m_cmdLineAttachPid(0),
@@ -682,14 +677,8 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
     cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY));
     mdebug->addAction(cmd);
 
-    cmd = am->registerAction(m_manager->m_nextIAction,
-        Constants::NEXTI, debuggercontext);
-    cmd->setDefaultKeySequence(QKeySequence(Constants::NEXTI_KEY));
-    mdebug->addAction(cmd);
-
-    cmd = am->registerAction(m_manager->m_stepIAction,
-        Constants::STEPI, debuggercontext);
-    cmd->setDefaultKeySequence(QKeySequence(Constants::STEPI_KEY));
+    cmd = am->registerAction(theDebuggerAction(StepByInstruction),
+        Constants::STEP_BY_INSTRUCTION, debuggercontext);
     mdebug->addAction(cmd);
 
     cmd = am->registerAction(m_manager->m_runToLineAction,
@@ -831,9 +820,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
     debugToolBarLayout->addWidget(toolButton(am->command(Constants::NEXT)->action()));
     debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEP)->action()));
     debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEPOUT)->action()));
-    debugToolBarLayout->addWidget(new Core::Utils::StyledSeparator);
-    debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEPI)->action()));
-    debugToolBarLayout->addWidget(toolButton(am->command(Constants::NEXTI)->action()));
+    debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEP_BY_INSTRUCTION)->action()));
 #ifdef USE_REVERSE_DEBUGGING
     debugToolBarLayout->addWidget(new Core::Utils::StyledSeparator);
     debugToolBarLayout->addWidget(toolButton(am->command(Constants::REVERSE)->action()));
@@ -892,8 +879,8 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
 
     connect(m_manager, SIGNAL(resetLocationRequested()),
         this, SLOT(resetLocation()));
-    connect(m_manager, SIGNAL(gotoLocationRequested(QString,int,bool)),
-        this, SLOT(gotoLocation(QString,int,bool)));
+    connect(m_manager, SIGNAL(gotoLocationRequested(StackFrame,bool)),
+        this, SLOT(gotoLocation(StackFrame,bool)));
     connect(m_manager, SIGNAL(statusChanged(int)),
         this, SLOT(changeStatus(int)));
     connect(m_manager, SIGNAL(previousModeRequested()),
@@ -1096,17 +1083,23 @@ void DebuggerPlugin::resetLocation()
     m_locationMark = 0;
 }
 
-void DebuggerPlugin::gotoLocation(const QString &fileName, int lineNumber,
-    bool setMarker)
+void DebuggerPlugin::gotoLocation(const StackFrame &frame, bool setMarker)
 {
-    TextEditor::BaseTextEditor::openEditorAt(fileName, lineNumber);
-    if (setMarker) {
-        resetLocation();
-        m_locationMark = new LocationMark(fileName, lineNumber);
+    if (theDebuggerBoolSetting(StepByInstruction) || !frame.isUsable()) {
+        if (!m_disassemblerViewAgent)
+            m_disassemblerViewAgent = new DisassemblerViewAgent(m_manager);
+        m_disassemblerViewAgent->setFrame(frame);
+        if (setMarker)
+            resetLocation();
+    } else {
+        TextEditor::BaseTextEditor::openEditorAt(frame.file, frame.line);
+        if (setMarker) {
+            resetLocation();
+            m_locationMark = new LocationMark(frame.file, frame.line);
+        }
     }
 }
 
-
 void DebuggerPlugin::changeStatus(int status)
 {
     bool startIsContinue = (status == DebuggerInferiorStopped);
@@ -1157,9 +1150,8 @@ void DebuggerPlugin::onModeChanged(IMode *mode)
      //        different then the debugger mode. E.g. Welcome and Help mode and
      //        also on shutdown.
 
-    if (mode != m_debugMode) {
+    if (mode != m_debugMode)
         return;
-    }
 
     EditorManager *editorManager = EditorManager::instance();
     if (editorManager->currentEditor())
diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h
index 01fe816d324..74928abe447 100644
--- a/src/plugins/debugger/debuggerplugin.h
+++ b/src/plugins/debugger/debuggerplugin.h
@@ -50,6 +50,8 @@ class IMode;
 
 namespace TextEditor {
 class ITextEditor;
+class ITextMark;
+class BaseTextMark;
 }
 
 namespace Debugger {
@@ -59,7 +61,8 @@ class BreakpointData;
 class DebuggerManager;
 class DebuggerRunner;
 class DebugMode;
-class LocationMark;
+class DisassemblerViewAgent;
+class StackFrame;
 
 class DebuggerPlugin : public ExtensionSystem::IPlugin
 {
@@ -94,7 +97,7 @@ private slots:
     void updateActions(int status);
 
     void resetLocation();
-    void gotoLocation(const QString &fileName, int line, bool setMarker);
+    void gotoLocation(const StackFrame &frame, bool setMarker);
 
     void breakpointSetRemoveMarginActionTriggered();
     void breakpointEnableDisableMarginActionTriggered();
@@ -127,7 +130,8 @@ private:
     DebuggerRunner *m_debuggerRunner;
 
     QString m_previousMode;
-    LocationMark *m_locationMark;
+    TextEditor::BaseTextMark *m_locationMark;
+    DisassemblerViewAgent *m_disassemblerViewAgent;
     int m_gdbRunningContext;
     unsigned m_cmdLineEnabledEngines;
     quint64 m_cmdLineAttachPid;
diff --git a/src/plugins/debugger/debuggertooltip.h b/src/plugins/debugger/debuggertooltip.h
index 59ff8807745..c543923381f 100644
--- a/src/plugins/debugger/debuggertooltip.h
+++ b/src/plugins/debugger/debuggertooltip.h
@@ -30,7 +30,7 @@
 #ifndef DEBUGGER_DEBUGGERTOOLTIP_H
 #define DEBUGGER_DEBUGGERTOOLTIP_H
 
-#include <qglobal.h>
+#include <QtCore/QtGlobal>
 
 QT_BEGIN_NAMESPACE
 class QAbstractItemModel;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 567f4e24dc5..74e8f6d13c9 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -970,11 +970,11 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record, const QVa
     qq->notifyInferiorStopped();
     q->showStatusMessage(tr("Run to Function finished. Stopped."));
     GdbMi frame = record.data.findChild("frame");
-    QString file = QString::fromLocal8Bit(frame.findChild("fullname").data());
-    int line = frame.findChild("line").data().toInt();
-    qDebug() << "HIT:" << file << line << "IN" << frame.toString()
-        << "--" << record.toString();
-    q->gotoLocation(file, line, true);
+    StackFrame f;
+    f.file = QString::fromLocal8Bit(frame.findChild("fullname").data());
+    f.line = frame.findChild("line").data().toInt();
+    f.address = _(frame.findChild("addr").data());
+    q->gotoLocation(f, true);
 }
 
 static bool isExitedReason(const QByteArray &reason)
@@ -1229,11 +1229,11 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
     qq->notifyInferiorStopped();
     q->showStatusMessage(tr("Run to Function finished. Stopped."));
     GdbMi frame = data.findChild("frame");
-    QString file = QString::fromLocal8Bit(frame.findChild("fullname").data());
-    int line = frame.findChild("line").data().toInt();
-    qDebug() << "HIT:" << file << line << "IN" << frame.toString()
-        << "--" << data.toString();
-    q->gotoLocation(file, line, true);
+    StackFrame f;
+    f.file = QString::fromLocal8Bit(frame.findChild("fullname").data());
+    f.line = frame.findChild("line").data().toInt();
+    f.address = _(frame.findChild("addr").data());
+    q->gotoLocation(f, true);
 #endif
 }
 
@@ -1853,6 +1853,9 @@ void GdbEngine::runToFunctionExec(const QString &functionName)
 
 void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
 {
+    StackFrame frame;
+    frame.file = fileName;
+    frame.line = lineNumber;
 #if 1
     // not available everywhere?
     //sendCliCommand(_("tbreak ") + fileName + ':' + QString::number(lineNumber));
@@ -1864,11 +1867,11 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
     //  ~"run1 (argc=1, argv=0x7fffbf1f5538) at test1.cpp:242"
     //  ~"242\t x *= 2;"
     //  23^done"
-    q->gotoLocation(fileName, lineNumber, true);
+    q->gotoLocation(frame, true);
     //setBreakpoint();
     //postCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
 #else
-    q->gotoLocation(fileName, lineNumber, true);
+    q->gotoLocation(frame,  true);
     setBreakpoint(fileName, lineNumber);
     postCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
 #endif
@@ -2566,13 +2569,9 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVari
     theDebuggerAction(ExpandStack)->setEnabled(canExpand);
     qq->stackHandler()->setFrames(stackFrames, canExpand);
 
-    if (topFrame != -1) {
-        // updates of locals already triggered early
+    if (topFrame != -1 || theDebuggerBoolSetting(StepByInstruction)) {
         const StackFrame &frame = qq->stackHandler()->currentFrame();
-        if (frame.isUsable())
-            q->gotoLocation(frame.file, frame.line, true);
-        else
-            qDebug() << "FULL NAME NOT USABLE 0:" << frame.file << topFrame;
+        q->gotoLocation(frame, true);
     }
 }
 
@@ -2622,7 +2621,7 @@ void GdbEngine::activateFrame(int frameIndex)
     const StackFrame &frame = stackHandler->currentFrame();
 
     if (frame.isUsable())
-        q->gotoLocation(frame.file, frame.line, true);
+        q->gotoLocation(frame, true);
     else
         qDebug() << "FULL NAME NOT USABLE:" << frame.file;
 }
@@ -4004,6 +4003,18 @@ void GdbEngine::handleWatchPoint(const GdbResultRecord &record, const QVariant &
     }
 }
 
+static QVariant agentCookie(void *agent)
+{
+    return QVariant(quint64(quintptr(agent)));
+}
+
+void GdbEngine::fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length)
+{
+    //qDebug() << "GDB MEMORY FETCH" << addr << length;
+    postCommand(_("-data-read-memory %1 x 1 1 %2").arg(addr).arg(length),
+        NeedsStop, CB(handleFetchMemory), agentCookie(agent));
+}
+
 void GdbEngine::handleFetchMemory(const GdbResultRecord &record,
     const QVariant &cookie)
 {
@@ -4017,7 +4028,7 @@ void GdbEngine::handleFetchMemory(const GdbResultRecord &record,
     QTC_ASSERT(agent, return);
     QByteArray ba;
     GdbMi memory = record.data.findChild("memory");
-    QTC_ASSERT(memory.children().size() == 1, return);
+    QTC_ASSERT(memory.children().size() <= 1, return);
     GdbMi memory0 = memory.children().at(0); // we asked for only one 'row'
     quint64 addr = memory0.findChild("addr").data().toULongLong(&ok, 0);
     QTC_ASSERT(ok, return);
@@ -4031,13 +4042,149 @@ void GdbEngine::handleFetchMemory(const GdbResultRecord &record,
     agent->addLazyData(addr, ba);
 }
 
-void GdbEngine::fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length)
+
+void GdbEngine::fetchDisassembler(DisassemblerViewAgent *agent,
+    const StackFrame &frame)
 {
-    //qDebug() << "GDB MEMORY FETCH" << addr << length;
-    postCommand(_("-data-read-memory %1 x 1 1 %2").arg(addr).arg(length),
-        NeedsStop, CB(handleFetchMemory), QVariant(quint64(agent)));
+    if (frame.file.isEmpty()) {
+        fetchDisassemblerByAddress(agent, true);
+    } else {
+        // Disassemble full function:
+        QString cmd = _("-data-disassemble -f %1 -l %2 -n -1 -- 1");
+        postCommand(cmd.arg(frame.file).arg(frame.line),
+            Discardable, CB(handleFetchDisassemblerByLine), agentCookie(agent));
+    }
+}
+
+void GdbEngine::fetchDisassemblerByAddress(DisassemblerViewAgent *agent,
+    bool useMixedMode)
+{
+    QTC_ASSERT(agent, return);
+    bool ok = true;
+    quint64 address = agent->address().toULongLong(&ok, 0);
+    quint64 start = address - 20;
+    quint64 end = address + 100;
+    // -data-disassemble [ -s start-addr -e end-addr ]
+    //  | [ -f filename -l linenum [ -n lines ] ] -- mode
+    if (useMixedMode) 
+        postCommand(_("-data-disassemble -s %1 -e %2 -- 1").arg(start).arg(end),
+            Discardable, CB(handleFetchDisassemblerByAddress1), agentCookie(agent));
+    else
+        postCommand(_("-data-disassemble -s %1 -e %2 -- 0").arg(start).arg(end),
+            Discardable, CB(handleFetchDisassemblerByAddress0), agentCookie(agent));
+}
+
+static QByteArray parseLine(const GdbMi &line)
+{
+    QByteArray ba;
+    ba.reserve(200);
+    QByteArray address = line.findChild("address").data();
+    QByteArray funcName = line.findChild("func-name").data();
+    QByteArray offset = line.findChild("offset").data();
+    QByteArray inst = line.findChild("inst").data();
+    ba += address + QByteArray(15 - address.size(), ' ');
+    ba += funcName + "+" + offset + "  ";
+    ba += QByteArray(30 - funcName.size() - offset.size(), ' ');
+    ba += inst;
+    ba += '\n';
+    return ba;
+}
+
+static QString parseDisassembler(const GdbMi &lines)
+{
+    // ^done,data={asm_insns=[src_and_asm_line={line="1243",file=".../app.cpp",
+    // line_asm_insn=[{address="0x08054857",func-name="main",offset="27",
+    // inst="call 0x80545b0 <_Z13testQFileInfov>"}]},
+    // src_and_asm_line={line="1244",file=".../app.cpp",
+    // line_asm_insn=[{address="0x0805485c",func-name="main",offset="32",
+    //inst="call 0x804cba1 <_Z11testObject1v>"}]}]}
+    // - or -
+    // ^done,asm_insns=[
+    // {address="0x0805acf8",func-name="...",offset="25",inst="and $0xe8,%al"},
+    // {address="0x0805acfa",func-name="...",offset="27",inst="pop %esp"},
+
+    QList<QByteArray> fileContents;
+    bool fileLoaded = false;
+    QByteArray ba;
+    ba.reserve(200 * lines.children().size());
+
+    // FIXME: Performance?
+    foreach (const GdbMi &child, lines.children()) {
+        if (child.hasName("src_and_asm_line")) {
+            // mixed mode
+            int line = child.findChild("line").data().toInt();
+            QByteArray fileName = child.findChild("file").data();
+            if (!fileLoaded) {
+                QFile file(QFile::decodeName(fileName));
+                file.open(QIODevice::ReadOnly);
+                fileContents = file.readAll().split('\n');
+                fileLoaded = true;
+            }
+            if (line >= 0 && line < fileContents.size())
+                ba += "             " + fileContents.at(line) + '\n';
+
+            GdbMi insn = child.findChild("line_asm_insn");
+            foreach (const GdbMi &line, insn.children()) 
+                ba += parseLine(line);
+        } else {
+            // the non-mixed version
+            ba += parseLine(child);
+        }
+    }
+    return _(ba);
 }
 
+void GdbEngine::handleFetchDisassemblerByLine(const GdbResultRecord &record,
+    const QVariant &cookie)
+{
+    bool ok = true;
+    DisassemblerViewAgent *agent = (DisassemblerViewAgent *)cookie.toULongLong(&ok);
+    QTC_ASSERT(agent, return);
+
+    if (record.resultClass == GdbResultDone) {
+        GdbMi lines = record.data.findChild("asm_insns");
+        if (lines.children().isEmpty())
+            fetchDisassemblerByAddress(agent, true);
+        else
+            agent->setContents(parseDisassembler(lines));
+    } else if (record.resultClass == GdbResultError) {
+        //536^error,msg="mi_cmd_disassemble: Invalid line number"
+        QByteArray msg = record.data.findChild("msg").data();
+        if (msg == "mi_cmd_disassemble: Invalid line number")
+            fetchDisassemblerByAddress(agent, true);
+    }
+}
+
+void GdbEngine::handleFetchDisassemblerByAddress1(const GdbResultRecord &record,
+    const QVariant &cookie)
+{
+    bool ok = true;
+    DisassemblerViewAgent *agent = (DisassemblerViewAgent *)cookie.toULongLong(&ok);
+    QTC_ASSERT(agent, return);
+
+    if (record.resultClass == GdbResultDone) {
+        GdbMi lines = record.data.findChild("asm_insns");
+        if (lines.children().isEmpty())
+            fetchDisassemblerByAddress(agent, false);
+        else
+            agent->setContents(parseDisassembler(lines));
+    }
+}
+
+void GdbEngine::handleFetchDisassemblerByAddress0(const GdbResultRecord &record,
+    const QVariant &cookie)
+{
+    bool ok = true;
+    DisassemblerViewAgent *agent = (DisassemblerViewAgent *)cookie.toULongLong(&ok);
+    QTC_ASSERT(agent, return);
+
+    if (record.resultClass == GdbResultDone) {
+        GdbMi lines = record.data.findChild("asm_insns");
+        agent->setContents(parseDisassembler(lines));
+    }
+}
+
+
 IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
 {
     opts->push_back(new GdbOptionsPage);
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 367b94856ce..3f16bd3701c 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -125,6 +125,17 @@ private:
     void fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length);
     void handleFetchMemory(const GdbResultRecord &record, const QVariant &cookie);
 
+    void fetchDisassembler(DisassemblerViewAgent *agent,
+        const StackFrame &frame);
+    void fetchDisassemblerByAddress(DisassemblerViewAgent *agent,
+        bool useMixedMode);
+    void handleFetchDisassemblerByLine(const GdbResultRecord &record,
+        const QVariant &cookie);
+    void handleFetchDisassemblerByAddress1(const GdbResultRecord &record,
+        const QVariant &cookie);
+    void handleFetchDisassemblerByAddress0(const GdbResultRecord &record,
+        const QVariant &cookie);
+
     Q_SLOT void setDebugDebuggingHelpers(const QVariant &on);
     Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
 
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index ad16fcec701..16b6d5ace5a 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -46,10 +46,12 @@ class ITextEditor;
 namespace Debugger {
 namespace Internal {
 
+class DebuggerStartParameters;
+class DisassemblerViewAgent;
+class MemoryViewAgent;
+class StackFrame;
 class Symbol;
 class WatchData;
-struct DebuggerStartParameters;
-class MemoryViewAgent;
 
 class IDebuggerEngine : public QObject
 {
@@ -98,6 +100,8 @@ public:
     virtual void watchPoint(const QPoint &) {}
     virtual void fetchMemory(MemoryViewAgent *, quint64 addr, quint64 length)
         { Q_UNUSED(addr); Q_UNUSED(length); }
+    virtual void fetchDisassembler(DisassemblerViewAgent *, const StackFrame &frame)
+        { Q_UNUSED(frame); }
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp
index 8639261b594..a4cd71d394f 100644
--- a/src/plugins/debugger/registerhandler.cpp
+++ b/src/plugins/debugger/registerhandler.cpp
@@ -76,6 +76,12 @@ QVariant RegisterHandler::data(const QModelIndex &index, int role) const
 
     const Register &reg = m_registers.at(index.row());
 
+    if (role == Qt::UserRole + 1) {
+        bool ok = true;
+        qulonglong value = reg.value.toULongLong(&ok, 0);
+        return QString::fromLatin1("0x") + QString::number(value, 16);
+    }
+
     const QString padding = "  ";
     if (role == Qt::DisplayRole) {
         switch (index.column()) {
diff --git a/src/plugins/debugger/registerwindow.cpp b/src/plugins/debugger/registerwindow.cpp
index 11a0340b6fa..2a8fd344373 100644
--- a/src/plugins/debugger/registerwindow.cpp
+++ b/src/plugins/debugger/registerwindow.cpp
@@ -30,6 +30,7 @@
 #include "registerwindow.h"
 
 #include "debuggeractions.h"
+#include "debuggeragents.h"
 #include "debuggerconstants.h"
 
 #include <QtCore/QDebug>
@@ -47,8 +48,9 @@
 using namespace Debugger::Internal;
 using namespace Debugger::Constants;
 
-RegisterWindow::RegisterWindow()
-  : m_alwaysResizeColumnsToContents(true), m_alwaysReloadContents(false)
+RegisterWindow::RegisterWindow(DebuggerManager *manager)
+  : m_manager(manager), m_alwaysResizeColumnsToContents(true),
+    m_alwaysReloadContents(false)
 {
     QAction *act = theDebuggerAction(UseAlternatingRowColors);
     setWindowTitle(tr("Registers"));
@@ -81,6 +83,17 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
     actAlwaysReload->setChecked(m_alwaysReloadContents);
     menu.addSeparator();
 
+    QModelIndex idx = indexAt(ev->pos());
+    QString address = model()->data(idx, Qt::UserRole + 1).toString();
+    QAction *actShowMemory = menu.addAction(QString());
+    if (address.isEmpty()) {
+        actShowMemory->setText(tr("Open memory editor"));
+        actShowMemory->setEnabled(false);
+    } else {
+        actShowMemory->setText(tr("Open memory editor at %1").arg(address));
+    }
+    menu.addSeparator();
+
     int base = model()->data(QModelIndex(), Qt::UserRole).toInt();
     QAction *act16 = menu.addAction(tr("Hexadecimal"));
     act16->setCheckable(true);
@@ -108,6 +121,8 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
         reloadContents();
     else if (act == actAlwaysReload)
         setAlwaysReloadContents(!m_alwaysReloadContents);
+    else if (act == actShowMemory)
+        (void) new MemoryViewAgent(m_manager, address);
     else if (act) {
         base = (act == act10 ? 10 : act == act8 ? 8 : act == act2 ? 2 : 16);
         QMetaObject::invokeMethod(model(), "setNumberBase", Q_ARG(int, base));
diff --git a/src/plugins/debugger/registerwindow.h b/src/plugins/debugger/registerwindow.h
index 4839c796137..f29283f3b54 100644
--- a/src/plugins/debugger/registerwindow.h
+++ b/src/plugins/debugger/registerwindow.h
@@ -35,12 +35,14 @@
 namespace Debugger {
 namespace Internal {
 
+class DebuggerManager;
+
 class RegisterWindow : public QTreeView
 {
     Q_OBJECT
 
 public:
-    RegisterWindow();
+    explicit RegisterWindow(DebuggerManager *manager);
     void setModel(QAbstractItemModel *model);
 
 signals:
@@ -57,6 +59,8 @@ private:
     void resizeEvent(QResizeEvent *ev);
     void contextMenuEvent(QContextMenuEvent *ev);
 
+    DebuggerManager *m_manager;
+
     bool m_alwaysResizeColumnsToContents;
     bool m_alwaysReloadContents;
 };
diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp
index a6f099ac9a3..44a9f610fc1 100644
--- a/src/plugins/debugger/script/scriptengine.cpp
+++ b/src/plugins/debugger/script/scriptengine.cpp
@@ -565,7 +565,10 @@ void ScriptEngine::maybeBreakNow(bool byFunction)
     }
 
     qq->notifyInferiorStopped();
-    q->gotoLocation(fileName, lineNumber, true);
+    StackFrame frame;
+    frame.file = fileName;      
+    frame.line = lineNumber;
+    q->gotoLocation(frame, true);
     updateLocals();
 }
 
diff --git a/src/plugins/debugger/stackframe.h b/src/plugins/debugger/stackframe.h
new file mode 100644
index 00000000000..35108aef3ef
--- /dev/null
+++ b/src/plugins/debugger/stackframe.h
@@ -0,0 +1,60 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_STACKFRAME_H
+#define DEBUGGER_STACKFRAME_H
+
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+
+namespace Debugger {
+namespace Internal {
+
+struct StackFrame
+{
+    StackFrame(int level = 0);    
+    bool isUsable() const;
+    QString toToolTip() const;
+    QString toString() const;
+
+    int level;
+    QString function;
+    QString file;  // we try to put an absolute file name in there
+    QString from;
+    QString to;
+    int line;
+    QString address;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+Q_DECLARE_METATYPE(Debugger::Internal::StackFrame);
+
+#endif // DEBUGGER_STACKFRAME_H
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index c315e4f9b64..e5bd3879f64 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -29,6 +29,8 @@
 
 #include "stackhandler.h"
 
+#include "debuggeractions.h"
+
 #include <utils/qtcassert.h>
 
 #include <QtCore/QAbstractTableModel>
@@ -46,6 +48,19 @@ bool StackFrame::isUsable() const
     return !file.isEmpty() && QFileInfo(file).isReadable();
 }
 
+QString StackFrame::toString() const
+{
+    QString res;
+    QTextStream str(&res);
+    str << StackHandler::tr("Address:") << " " << address << " "
+        << StackHandler::tr("Function:") << " " << function << " "
+        << StackHandler::tr("File:") << " " << file << " "
+        << StackHandler::tr("Line:") << " " << line << " "
+        << StackHandler::tr("From:") << " " << from << " "
+        << StackHandler::tr("To:") << " " << to;
+    return res;
+}
+
 QString StackFrame::toToolTip() const
 {
     QString res;
@@ -117,14 +132,22 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
         case 4: // Address
             return frame.address;
         }
-    } else if (role == Qt::ToolTipRole) {
+        return QVariant();
+    }
+
+    if (role == Qt::ToolTipRole) {
         //: Tooltip for variable
         return frame.toToolTip();
-    } else if (role == Qt::DecorationRole && index.column() == 0) {
+    }
+
+    if (role == Qt::DecorationRole && index.column() == 0) {
         // Return icon that indicates whether this is the active stack frame
         return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon;
     }
 
+    if (role == Qt::UserRole)
+        return QVariant::fromValue(frame);
+
     return QVariant();
 }
 
@@ -149,7 +172,8 @@ Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
     if (index.row() == m_stackFrames.size())
         return QAbstractTableModel::flags(index);
     const StackFrame &frame = m_stackFrames.at(index.row());
-    const bool isValid = (!frame.file.isEmpty() && !frame.function.isEmpty());
+    const bool isValid = (!frame.file.isEmpty() && !frame.function.isEmpty())
+        || theDebuggerBoolSetting(StepByInstruction);
     return isValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0);
 }
 
diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h
index 63f49e6c525..3fee2a5f872 100644
--- a/src/plugins/debugger/stackhandler.h
+++ b/src/plugins/debugger/stackhandler.h
@@ -30,11 +30,14 @@
 #ifndef DEBUGGER_STACKHANDLER_H
 #define DEBUGGER_STACKHANDLER_H
 
+#include "stackframe.h"
+
 #include <QtCore/QAbstractTableModel>
 #include <QtCore/QObject>
 
 #include <QtGui/QIcon>
 
+
 namespace Debugger {
 namespace Internal {
 
@@ -44,21 +47,6 @@ namespace Internal {
 //
 ////////////////////////////////////////////////////////////////////////
 
-struct StackFrame
-{
-    StackFrame(int level = 0);    
-    bool isUsable() const;
-    QString toToolTip() const;
-
-    int level;
-    QString function;
-    QString file;  // we try to put an absolute file name in there
-    QString from;
-    QString to;
-    int line;
-    QString address;
-};
-
 /*! A model to represent the stack in a QTreeView. */
 class StackHandler : public QAbstractTableModel
 {
diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp
index 2bb9d721b7b..1f397b5114f 100644
--- a/src/plugins/debugger/stackwindow.cpp
+++ b/src/plugins/debugger/stackwindow.cpp
@@ -28,8 +28,10 @@
 **************************************************************************/
 
 #include "stackwindow.h"
+#include "stackframe.h"
 
 #include "debuggeractions.h"
+#include "debuggeragents.h"
 
 #include <utils/qtcassert.h>
 
@@ -46,11 +48,14 @@
 #include <QtGui/QVBoxLayout>
 
 
-using Debugger::Internal::StackWindow;
+namespace Debugger {
+namespace Internal {
 
-StackWindow::StackWindow(QWidget *parent)
-    : QTreeView(parent), m_alwaysResizeColumnsToContents(false)
+StackWindow::StackWindow(DebuggerManager *manager, QWidget *parent)
+    : QTreeView(parent), m_manager(manager), m_alwaysResizeColumnsToContents(false)
 {
+    m_disassemblerAgent = new DisassemblerViewAgent(manager);
+
     QAction *act = theDebuggerAction(UseAlternatingRowColors);
     setWindowTitle(tr("Stack"));
 
@@ -90,33 +95,60 @@ void StackWindow::rowActivated(const QModelIndex &index)
 
 void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
 {
+    QModelIndex idx = indexAt(ev->pos());
+    StackFrame frame = model()->data(idx, Qt::UserRole).value<StackFrame>();
+    QString address = frame.address;
+    
+    qDebug() << "RECV: " << frame.toToolTip();
+
     QMenu menu;
 
-    QAction *act0 = new QAction(tr("Copy contents to clipboard"), &menu);
-    act0->setEnabled(model() != 0);
+    QAction *actAdjust = menu.addAction(tr("Adjust column widths to contents"));
 
-    QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
+    QAction *actAlwaysAdjust =
+        menu.addAction(tr("Always adjust column widths to contents"));
+    actAlwaysAdjust->setCheckable(true);
+    actAlwaysAdjust->setChecked(m_alwaysResizeColumnsToContents);
 
-    QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
-    act2->setCheckable(true);
-    act2->setChecked(m_alwaysResizeColumnsToContents);
+    menu.addSeparator();
 
     menu.addAction(theDebuggerAction(ExpandStack));
-    menu.addAction(act0);
-    menu.addSeparator();
-    menu.addAction(act1);
-    menu.addAction(act2);
+
+    QAction *actCopyContents = menu.addAction(tr("Copy contents to clipboard"));
+    actCopyContents->setEnabled(model() != 0);
+
+    QAction *actShowMemory = menu.addAction(QString());
+    if (address.isEmpty()) {
+        actShowMemory->setText(tr("Open memory editor"));
+        actShowMemory->setEnabled(false);
+    } else {
+        actShowMemory->setText(tr("Open memory editor at %1").arg(address));
+    }
+
+    QAction *actShowDisassembler = menu.addAction(QString());
+    if (address.isEmpty()) {
+        actShowDisassembler->setText(tr("Open disassembler"));
+        actShowDisassembler->setEnabled(false);
+    } else {
+        actShowDisassembler->setText(tr("Open disassembler at %1").arg(address));
+    }
+
     menu.addSeparator();
+
     menu.addAction(theDebuggerAction(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
-    if (act == act0)
+    if (act == actCopyContents)
         copyContentsToClipboard();
-    else if (act == act1)
+    else if (act == actAdjust)
         resizeColumnsToContents();
-    else if (act == act2)
+    else if (act == actAlwaysAdjust)
         setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
+    else if (act == actShowMemory)
+        (void) new MemoryViewAgent(m_manager, address);
+    else if (act == actShowDisassembler)
+        m_disassemblerAgent->setFrame(frame);
 }
 
 void StackWindow::copyContentsToClipboard()
@@ -157,3 +189,6 @@ void StackWindow::setAlwaysResizeColumnsToContents(bool on)
     header()->setResizeMode(2, mode);
     header()->setResizeMode(3, mode);
 }
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/stackwindow.h b/src/plugins/debugger/stackwindow.h
index 42bc03749ce..2703735420e 100644
--- a/src/plugins/debugger/stackwindow.h
+++ b/src/plugins/debugger/stackwindow.h
@@ -40,13 +40,16 @@ QT_END_NAMESPACE
 
 namespace Debugger {
 namespace Internal {
+
+class DebuggerManager;
+class DisassemblerViewAgent;
     
 class StackWindow : public QTreeView
 {
     Q_OBJECT
 
 public:
-    StackWindow(QWidget *parent = 0);
+    StackWindow(DebuggerManager *manager, QWidget *parent = 0);
 
 signals:
     void frameActivated(int);
@@ -64,6 +67,8 @@ private:
     void contextMenuEvent(QContextMenuEvent *ev);
     void copyContentsToClipboard();
 
+    DebuggerManager *m_manager;
+    DisassemblerViewAgent *m_disassemblerAgent;
     bool m_alwaysResizeColumnsToContents;
 };
 
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index 6d090bf585a..a41c6721a9a 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -297,9 +297,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
         theDebuggerAction(WatchExpression)
             ->trigger(WatchHandler::watcherEditPlaceHolder());
     } else if (act == actWatchKnownMemory) {
-        bool ok = true;
-        uint addr = address.toUInt(&ok, 0);
-        (void) new MemoryViewAgent(m_manager, addr);
+        (void) new MemoryViewAgent(m_manager, address);
     } else if (act == actWatchUnknownMemory) {
         QLabel *label = new QLabel("Enter an address: ");
         QLineEdit *lineEdit = new QLineEdit;
@@ -310,11 +308,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
         dialog.setWindowTitle("Select start address");
         dialog.setLayout(layout);
         connect(lineEdit, SIGNAL(returnPressed()), &dialog, SLOT(accept()));
-        if (dialog.exec() == QDialog::Accepted) {
-            bool ok = true;
-            uint addr = lineEdit->text().toUInt(&ok, 0);
-            (void) new MemoryViewAgent(m_manager, addr);
-        }
+        if (dialog.exec() == QDialog::Accepted)
+            (void) new MemoryViewAgent(m_manager, address);
     } else if (act == actSelectWidgetToWatch) {
         grabMouse(Qt::CrossCursor);
         m_grabbing = true;
-- 
GitLab