summaryrefslogtreecommitdiff
path: root/src/plugins/debugger/cdb/cdbdumperhelper.h
blob: a7742685e8deae1f2b015e43fd756b62398b2ded (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 CDBDUMPERHELPER_H
#define CDBDUMPERHELPER_H

#include "watchutils.h"
#include "cdbcom.h"

#include <QtCore/QStringList>
#include <QtCore/QMap>

namespace CdbCore {
    class CoreEngine;
    struct ComInterfaces;
}

namespace Debugger {
class DebuggerManager;

namespace Internal {
class CdbDumperInitThread;

/* For code clarity, all the stuff related to custom dumpers goes here.
 * "Custom dumper" is a library compiled against the current
 * Qt containing functions to evaluate values of Qt classes
 * (such as QString), taking pointers to their addresses.
 * The dumper functions produce formatted string output which is
 * converted into WatchData items with the help of QtDumperHelper.
 *
 * Usage: When launching the debugger, call reset() with path to dumpers
 * and enabled flag. From the module load event callback, call
 * moduleLoadHook() to initialize.
 * dumpType() is the main query function to obtain a list  of WatchData from
 * WatchData item produced by the smbol context.
 * Call disable(), should the debuggee crash (as performing debuggee
 * calls is no longer possible, then).
 *
 * dumperCallThread specifies the thread to use when making the calls.
 * As of Debugging Tools v 6.11.1.404 (6.10.2009), calls cannot be executed
 * when the current thread is in some WaitFor...() function. The call will
 * then hang (regardless whether that thread or some other, non-blocking thread
 * is used), and the debuggee will be in running state afterwards (causing errors
 * from ReadVirtual, etc).
 * The current thread can be used when stepping or a breakpoint was
 * hit. When interrupting the inferior, an artifical thread is created,
 * that is not usable, either. */

class CdbDumperHelper
{
    Q_DISABLE_COPY(CdbDumperHelper)
public:
   enum State {
        Disabled, // Disabled or failed
        NotLoaded,
        InjectLoadFailed,
        InjectLoading,
        Loaded,
        Initialized, // List of types, etc. retrieved
    };

    explicit CdbDumperHelper(DebuggerManager *manager,
                             CdbCore::CoreEngine *coreEngine);
    ~CdbDumperHelper();

    State state() const    { return m_state; }
    bool isEnabled() const { return m_state != Disabled; }

    // Disable in case of a debuggee crash.
    void disable();

    // Call before starting the debugger
    void reset(const QString &library, bool enabled);

    // Call from the module load callback to perform initialization.
    void moduleLoadHook(const QString &module, HANDLE debuggeeHandle);

    // Dump a WatchData item.
    enum DumpResult { DumpNotHandled, DumpOk, DumpError };
    DumpResult dumpType(const WatchData &d, bool dumpChildren,
                        QList<WatchData> *result, QString *errorMessage);

    const CdbCore::ComInterfaces *comInterfaces() const;

    enum { InvalidDumperCallThread = 0xFFFFFFFF };
    unsigned long dumperCallThread();
    void setDumperCallThread(unsigned long t);

private:
    friend class CdbDumperInitThread;
    enum CallLoadResult { CallLoadOk, CallLoadError, CallLoadNoQtApp, CallLoadAlreadyLoaded };

    void clearBuffer();
    CallLoadResult initCallLoad(QString *errorMessage);
    bool initResolveSymbols(QString *errorMessage);
    bool initKnownTypes(QString *errorMessage);

    inline DumpResult dumpTypeI(const WatchData &d, bool dumpChildren,
                                QList<WatchData> *result, QString *errorMessage);

    bool getTypeSize(const QString &typeName, int *size, QString *errorMessage);
    bool runTypeSizeQuery(const QString &typeName, int *size, QString *errorMessage);
    enum CallResult { CallOk, CallSyntaxError, CallFailed };
    CallResult callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr,
                          bool ignoreAccessViolation, QString *errorMessage);

    enum DumpExecuteResult { DumpExecuteOk, DumpExpressionFailed, DumpExecuteCallFailed };
    DumpExecuteResult executeDump(const WatchData &wd,
                                  const QtDumperHelper::TypeData& td, bool dumpChildren,
                                  QList<WatchData> *result, QString *errorMessage);

    const bool m_tryInjectLoad;
    const QString m_msgDisabled;
    const QString m_msgNotInScope;
    State m_state;
    DebuggerManager *m_manager;
    CdbCore::CoreEngine *m_coreEngine;

    QString m_library;
    QString m_dumpObjectSymbol;

    quint64 m_inBufferAddress;
    unsigned long m_inBufferSize;
    quint64 m_outBufferAddress;
    unsigned long m_outBufferSize;
    char *m_buffer;

    QStringList m_failedTypes;

    QtDumperHelper m_helper;
    unsigned long m_dumperCallThread;
    QString m_goCommand;
};

} // namespace Internal
} // namespace Debugger

#endif // CDBDUMPERHELPER_H