1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  */
5 
6 #ifndef DEBUGGER_DEFS_H
7 #define DEBUGGER_DEFS_H
8 
9 #include <wx/string.h>
10 #include <wx/dynarray.h>
11 #include <deque>
12 #include <vector>
13 #include <unordered_map>
14 
15 #include "debuggermanager.h"
16 #include "cbplugin.h"
17 
18 class DebuggerDriver;
19 
20 extern const int DEBUGGER_CURSOR_CHANGED; ///< wxCommandEvent ID fired when the cursor has changed.
21 extern const int DEBUGGER_SHOW_FILE_LINE; ///< wxCommandEvent ID fired to display a file/line (w/out changing the cursor)
22 
23 /** Debugger cursor info.
24   *
25   * Contains info about the debugger's cursor, i.e. where it currently is at
26   * (file, line, function, address).
27   */
28 struct Cursor
29 {
CursorCursor30     Cursor() : line(-1), changed(false) {}
31     wxString file;
32     wxString address;
33     wxString function;
34     long int line; ///< If -1, no line info
35     bool changed;
36 };
37 
38 /** Basic interface for debugger commands.
39   *
40   * Each command sent to the debugger, is a DebuggerCmd.
41   * It encapsulates the call and parsing of return values.
42   * The most important function is ParseOutput() inside
43   * which it must parse the commands output.
44   * It is guaranteed that the @c output argument to ParseOutput()
45   * contains the full debugger response to the command given.
46   *
47   * @remarks This is not an abstract interface, i.e. you can
48   * create instances of it. The default implementation just
49   * logs the command's output. This way you can debug new commands.
50   */
51 class DebuggerCmd
52 {
53     public:
54         DebuggerCmd(DebuggerDriver* driver, const wxString& cmd = _T(""), bool logToNormalLog = false);
~DebuggerCmd()55         virtual ~DebuggerCmd(){}
56 
57         /** Executes an action.
58           *
59           * This allows for "dummy" debugger commands to enter the commands queue.
60           * You can, for example, leave m_Cmd empty and just have Action()
61           * do something GUI-related (like the watches command does).
62           * Action() is called when the debugger command becomes current in the
63           * commands queue. It is called after sending m_Cmd to the debugger (if not empty).
64           */
Action()65         virtual void Action(){}
66 
67         /** Parses the command's output.
68           * @param The output. This is the full output up to
69           * (and including) the prompt.
70           */
71         virtual void ParseOutput(const wxString& output);
72 
73         /** Tells if the command is a continue type command (continue, step, next and run to cursor
74           * commands should be marked as such)
75           * @return true if the command is continue type command
76           */
IsContinueCommand()77         virtual bool IsContinueCommand() const { return false; }
78 
79         wxString m_Cmd;         ///< the actual command
80     protected:
81         DebuggerDriver* m_pDriver; ///< the driver
82         bool m_LogToNormalLog;  ///< if true, log to normal log, else the debug log
83 };
84 
85 /** This command is similar to DebuggerCmd
86   * The only difference is that instead of logging its output in the debugger log,
87   * it displays it in a dialog.
88   */
89 class DebuggerInfoCmd : public DebuggerCmd
90 {
91     public:
DebuggerInfoCmd(DebuggerDriver * driver,const wxString & cmd,const wxString & title)92         DebuggerInfoCmd(DebuggerDriver* driver, const wxString& cmd, const wxString& title)
93             : DebuggerCmd(driver, cmd),
94             m_Title(title)
95         {
96             m_Cmd = cmd;
97         }
~DebuggerInfoCmd()98         virtual ~DebuggerInfoCmd(){}
99 
100         virtual void ParseOutput(const wxString& output);
101         wxString m_Title;
102 };
103 
104 /** Base class for all Continue type of commands */
105 class DebuggerContinueBaseCmd : public DebuggerCmd
106 {
107     public:
108         DebuggerContinueBaseCmd(DebuggerDriver* driver, const wxString& cmd = _T(""), bool logToNormalLog = false) :
DebuggerCmd(driver,cmd,logToNormalLog)109             DebuggerCmd(driver, cmd, logToNormalLog)
110         {
111         }
112 
IsContinueCommand()113         bool IsContinueCommand() const { return true; }
114 };
115 
116 /** Action-only debugger command to signal the watches tree to update. */
117 class DbgCmd_UpdateWindow : public DebuggerCmd
118 {
119     public:
120         DbgCmd_UpdateWindow(DebuggerDriver* driver, cbDebuggerPlugin::DebugWindows windowToUpdate);
121         void Action() override;
122 
123     private:
124         cbDebuggerPlugin::DebugWindows m_windowToUpdate;
125 };
126 
127 /** Debugger breakpoint interface.
128   *
129   * This is the struct used for debugger breakpoints.
130   */
131 ////////////////////////////////////////////////////////////////////////////////
132 struct DebuggerBreakpoint : cbBreakpoint
133 {
134     enum BreakpointType
135     {
136         bptCode = 0,    ///< Normal file/line breakpoint
137         bptFunction,    ///< Function signature breakpoint
138         bptData            ///< Data breakpoint
139     };
140 
141     /** Constructor.
142       * Sets default values for members.
143       */
DebuggerBreakpointDebuggerBreakpoint144     DebuggerBreakpoint()
145         : type(bptCode),
146         line(0),
147         index(-1),
148         temporary(false),
149         enabled(true),
150         active(true),
151         useIgnoreCount(false),
152         ignoreCount(0),
153         useCondition(false),
154         wantsCondition(false),
155         address(0),
156         alreadySet(false),
157         breakOnRead(false),
158         breakOnWrite(true),
159         userData(0)
160     {}
161 
162     // from cbBreakpoint
163     virtual void SetEnabled(bool flag);
164     virtual wxString GetLocation() const;
165     virtual int GetLine() const;
166     virtual wxString GetLineString() const;
167     virtual wxString GetType() const;
168     virtual wxString GetInfo() const;
169     virtual bool IsEnabled() const;
170     virtual bool IsVisibleInEditor() const;
171     virtual bool IsTemporary() const;
172 
173     BreakpointType type; ///< The type of this breakpoint.
174     wxString filename; ///< The filename for the breakpoint (kept as relative).
175     wxString filenameAsPassed; ///< The filename for the breakpoint as passed to the debugger (i.e. full filename).
176     int line; ///< The line for the breakpoint.
177     long int index; ///< The breakpoint number. Set automatically. *Don't* write to it.
178     bool temporary; ///< Is this a temporary (one-shot) breakpoint?
179     bool enabled; ///< Is the breakpoint enabled?
180     bool active; ///< Is the breakpoint active? (currently unused)
181     bool useIgnoreCount; ///< Should this breakpoint be ignored for the first X passes? (@c x == @c ignoreCount)
182     int ignoreCount; ///< The number of passes before this breakpoint should hit. @c useIgnoreCount must be true.
183     bool useCondition; ///< Should this breakpoint hit only if a specific condition is met?
184     bool wantsCondition; ///< Evaluate condition for pending breakpoints at first stop !
185     wxString condition; ///< The condition that must be met for the breakpoint to hit. @c useCondition must be true.
186     wxString func; ///< The function to set the breakpoint. If this is set, it is preferred over the filename/line combination.
187     unsigned long int address; ///< The actual breakpoint address. This is read back from the debugger. *Don't* write to it.
188     bool alreadySet; ///< Is this already set? Used to mark temporary breakpoints for removal.
189     wxString lineText; ///< Optionally, the breakpoint line's text (used by GDB for setting breapoints on ctors/dtors).
190     wxString breakAddress; ///< Valid only for type==bptData: address to break when read/written.
191     bool breakOnRead; ///< Valid only for type==bptData: break when memory is read from.
192     bool breakOnWrite; ///< Valid only for type==bptData: break when memory is written to.
193     void* userData; ///< Custom user data.
194 };
195 typedef std::deque<cb::shared_ptr<DebuggerBreakpoint> > BreakpointsList;
196 
197 /** Watch variable format.
198   *
199   * @note not all formats are implemented for all debugger drivers.
200   */
201 enum WatchFormat
202 {
203     Undefined = 0, ///< Format is undefined (whatever the debugger uses by default).
204     Decimal, ///< Variable should be displayed as decimal.
205     Unsigned, ///< Variable should be displayed as unsigned.
206     Hex, ///< Variable should be displayed as hexadecimal (e.g. 0xFFFFFFFF).
207     Binary, ///< Variable should be displayed as binary (e.g. 00011001).
208     Char, ///< Variable should be displayed as a single character (e.g. 'x').
209     Float, ///< Variable should be displayed as floating point number (e.g. 14.35)
210 
211     // do not remove these
212     Last, ///< used for iterations
213     Any ///< used for watches searches
214 };
215 
216 class GDBWatch : public cbWatch
217 {
218     public:
219         GDBWatch(wxString const &symbol);
220         virtual ~GDBWatch();
221     public:
222 
223         virtual void GetSymbol(wxString &symbol) const;
224         virtual void GetValue(wxString &value) const;
225         virtual bool SetValue(const wxString &value);
226         virtual void GetFullWatchString(wxString &full_watch) const;
227         virtual void GetType(wxString &type) const;
228         virtual void SetType(const wxString &type);
229 
230         virtual wxString GetDebugString() const;
231 
232         wxString MakeSymbolToAddress() const override;
233         bool IsPointerType() const override;
234     public:
235         void SetDebugValue(wxString const &value);
236         void SetSymbol(const wxString& symbol);
237 
238         void SetFormat(WatchFormat format);
239         WatchFormat GetFormat() const;
240 
241         void SetArray(bool flag);
242         bool IsArray() const;
243         void SetArrayParams(int start, int count);
244         int GetArrayStart() const;
245         int GetArrayCount() const;
246 
247         void SetForTooltip(bool flag = true);
248         bool GetForTooltip() const;
249 
250     protected:
251         virtual void DoDestroy();
252 
253     private:
254         wxString m_symbol;
255         wxString m_type;
256         wxString m_raw_value;
257         wxString m_debug_value;
258         WatchFormat m_format;
259         int m_array_start;
260         int m_array_count;
261         bool m_is_array;
262         bool m_forTooltip;
263 };
264 
265 class GDBMemoryRangeWatch  : public cbWatch
266 {
267     public:
268         GDBMemoryRangeWatch(uint64_t address, uint64_t size, const wxString& symbol);
269 
270     public:
GetSymbol(wxString & symbol)271         void GetSymbol(wxString &symbol) const override { symbol = m_symbol; }
GetValue(wxString & value)272         void GetValue(wxString &value) const override { value = m_value; }
273         bool SetValue(const wxString &value) override;
GetFullWatchString(wxString & full_watch)274         void GetFullWatchString(wxString &full_watch) const override { full_watch = wxEmptyString; }
GetType(wxString & type)275         void GetType(wxString &type) const override { type = wxT("Memory range"); }
SetType(cb_unused const wxString & type)276         void SetType(cb_unused const wxString &type) override {}
277 
GetDebugString()278         wxString GetDebugString() const override { return wxString(); }
279 
280         wxString MakeSymbolToAddress() const override;
IsPointerType()281         bool IsPointerType() const override { return false; }
282 
GetAddress()283         uint64_t GetAddress() const { return m_address; }
GetSize()284         uint64_t GetSize() const { return m_size; }
285 
286     private:
287         uint64_t m_address;
288         uint64_t m_size;
289         wxString m_symbol;
290         wxString m_value;
291 };
292 
293 typedef std::vector<cb::shared_ptr<GDBWatch>> WatchesContainer;
294 typedef std::vector<cb::shared_ptr<GDBMemoryRangeWatch>> MemoryRangeWatchesContainer;
295 
296 
297 enum class WatchType
298 {
299     Normal,
300     MemoryRange
301 };
302 
303 typedef std::unordered_map<cb::shared_ptr<cbWatch>, WatchType> MapWatchesToType;
304 
305 bool IsPointerType(wxString type);
306 wxString CleanStringValue(wxString value);
307 
308 enum DebuggerLanguage
309 {
310     dl_Cpp = 0, ///< C++ or C language.
311     dl_Fortran  ///< Fortran language.
312 };
313 
314 extern DebuggerLanguage g_DebugLanguage;
315 
316 
317 #endif // DEBUGGER_DEFS_H
318