1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  */
5 
6 #ifndef X_DEBUGGER_MANAGER_H
7 #define X_DEBUGGER_MANAGER_H
8 
9 #include <map>
10 #include <vector>
11 
12 #include <wx/string.h>
13 
14 #include "prep.h"
15 #include "settings.h"
16 #include "manager.h"
17 #include "configmanager.h"
18 
19 class wxMenu;
20 class wxToolBar;
21 class cbBacktraceDlg;
22 class cbBreakpointsDlg;
23 class cbCPURegistersDlg;
24 class cbDebuggerPlugin;
25 class cbDebugInterfaceFactory;
26 class cbDisassemblyDlg;
27 class cbExamineMemoryDlg;
28 class cbThreadsDlg;
29 class cbWatchesDlg;
30 class cbDebuggerMenuHandler;
31 class TextCtrlLogger;
32 
33 class DLLIMPORT cbBreakpoint
34 {
35     public:
~cbBreakpoint()36         virtual ~cbBreakpoint() {}
37 
38         virtual void SetEnabled(bool flag) = 0;
39         virtual wxString GetLocation() const = 0;
40         virtual int GetLine() const = 0;
41         virtual wxString GetLineString() const = 0;
42         virtual wxString GetType() const = 0;
43         virtual wxString GetInfo() const = 0;
44         virtual bool IsEnabled() const = 0;
45         virtual bool IsVisibleInEditor() const = 0;
46         virtual bool IsTemporary() const = 0;
47 };
48 
49 class DLLIMPORT cbWatch
50 {
51         cbWatch& operator =(cbWatch &);
52         cbWatch(cbWatch &);
53 
54     public:
55         cbWatch();
56     public:
57         virtual void GetSymbol(wxString &symbol) const = 0;
58         virtual void GetValue(wxString &value) const = 0;
59         virtual bool SetValue(const wxString &value) = 0;
60         virtual void GetFullWatchString(wxString &full_watch) const = 0;
61         virtual void GetType(wxString &type) const = 0;
62         virtual void SetType(const wxString &type) = 0;
63 
64         virtual wxString GetDebugString() const = 0;
65         /// This should return a string that when passed to the debugger will return the address of the variable.
66         /// For example for C/C++ languages for myVar this function will return &myVar.
67         virtual wxString MakeSymbolToAddress() const;
68         /// Tells us if the watch is for pointer variable.
69         virtual bool IsPointerType() const;
70     protected:
71         virtual ~cbWatch();
72     public:
73         static void AddChild(cb::shared_ptr<cbWatch> parent, cb::shared_ptr<cbWatch> watch);
74         void RemoveChild(int index);
75         void RemoveChildren();
76         bool RemoveMarkedChildren();
77         int GetChildCount() const;
78         cb::shared_ptr<cbWatch> GetChild(int index);
79         cb::shared_ptr<const cbWatch> GetChild(int index) const;
80 
81         cb::shared_ptr<cbWatch> FindChild(const wxString& name);
82         int FindChildIndex(const wxString& symbol) const;
83 
84         cb::shared_ptr<const cbWatch> GetParent() const;
85         cb::shared_ptr<cbWatch> GetParent();
86 
87         bool IsRemoved() const;
88         bool IsChanged() const;
89 
90         void MarkAsRemoved(bool flag);
91         void MarkChildsAsRemoved();
92         void MarkAsChanged(bool flag);
93         void MarkAsChangedRecursive(bool flag);
94 
95         bool IsExpanded() const;
96         void Expand(bool expand);
97 
98         bool IsAutoUpdateEnabled() const;
99         void AutoUpdate(bool enabled);
100     private:
101         cb::weak_ptr<cbWatch> m_parent;
102         std::vector<cb::shared_ptr<cbWatch> >    m_children;
103         bool            m_changed;
104         bool            m_removed;
105         bool            m_expanded;
106         bool            m_autoUpdate;
107 };
108 
109 cb::shared_ptr<cbWatch> DLLIMPORT cbGetRootWatch(cb::shared_ptr<cbWatch> watch);
110 
111 class DLLIMPORT cbStackFrame
112 {
113     public:
114         cbStackFrame();
115 
116         void SetNumber(int number);
117         void SetAddress(uint64_t address);
118         void SetSymbol(const wxString& symbol);
119         void SetFile(const wxString& filename, const wxString &line);
120         void MakeValid(bool flag);
121 
122         int GetNumber() const;
123         uint64_t GetAddress() const;
124         wxString GetAddressAsString() const;
125         const wxString& GetSymbol() const;
126         const wxString& GetFilename() const;
127         const wxString& GetLine() const;
128         bool IsValid() const;
129     private:
130         bool m_valid; ///< Is this stack frame valid?
131         int m_number; ///< Stack frame's number (used in backtraces).
132         uint64_t m_address; ///< Stack frame's address.
133         wxString m_symbol; ///< Current function name.
134         wxString m_file; ///< Current file.
135         wxString m_line; ///< Current line in file.
136 };
137 
138 class DLLIMPORT cbThread
139 {
140     public:
141         cbThread();
142         cbThread(bool active, int number, const wxString& info);
143 
144         bool IsActive() const;
145         int GetNumber() const;
146         const wxString& GetInfo() const;
147 
148     private:
149         bool m_active;
150         int m_number;
151         wxString m_info;
152 };
153 
154 /**
155   *
156   */
157 class DLLIMPORT cbDebuggerConfiguration
158 {
159     protected:
160         cbDebuggerConfiguration(const cbDebuggerConfiguration &o);
161         cbDebuggerConfiguration& operator =(const cbDebuggerConfiguration &);
162 
163     public:
164         cbDebuggerConfiguration(const ConfigManagerWrapper &config);
~cbDebuggerConfiguration()165         virtual ~cbDebuggerConfiguration() {}
166 
167         virtual cbDebuggerConfiguration* Clone() const = 0;
168 
169         virtual wxPanel* MakePanel(wxWindow *parent) = 0;
170         virtual bool SaveChanges(wxPanel *panel) = 0;
171 
172         void SetName(const wxString &name);
173         const wxString& GetName() const;
174 
175         const ConfigManagerWrapper& GetConfig() const;
176         void SetConfig(const ConfigManagerWrapper &config);
177 
178         void SetMenuId(long id);
179         long GetMenuId() const;
180 
181     protected:
182         ConfigManagerWrapper m_config;
183     private:
184         wxString m_name;
185         long m_menuId;
186 };
187 
188 /**
189   *
190   */
191 struct DLLIMPORT cbDebuggerCommonConfig
192 {
193     enum Flags
194     {
195         AutoBuild = 0,
196         AutoSwitchFrame,
197         ShowDebuggersLog,
198         JumpOnDoubleClick,
199         RequireCtrlForTooltips,
200         ShowTemporaryBreakpoints
201     };
202 
203     enum Perspective
204     {
205         OnlyOne = 0,
206         OnePerDebugger,
207         OnePerDebuggerConfig
208     };
209 
210     static bool GetFlag(Flags flag);
211     static void SetFlag(Flags flag, bool value);
212 
213     static wxString GetValueTooltipFont();
214     static void SetValueTooltipFont(const wxString &font);
215 
216     static Perspective GetPerspective();
217     static void SetPerspective(int perspective);
218 };
219 
220 /**
221   * Tries to detect the path to the debugger's executable.
222   */
223 DLLIMPORT wxString cbDetectDebuggerExecutable(const wxString &exeName);
224 
225 /** Convert a string in hex form to a uint64_t number.
226  * \return The uint64_t representation of the string or 0 when the string can't be converted.
227  */
228 DLLIMPORT uint64_t cbDebuggerStringToAddress(const wxString &address);
229 
230 /** Convert a uint64_t variable to a hex string that will look like an address. */
231 DLLIMPORT wxString cbDebuggerAddressToString(uint64_t address);
232 
233 class DLLIMPORT DebuggerManager : public Mgr<DebuggerManager>
234 {
235     private:
236         DebuggerManager();
237         ~DebuggerManager() override;
238 
239         friend class Mgr<DebuggerManager>;
240         friend class Manager;
241     public:
242         typedef std::vector<cbDebuggerConfiguration*> ConfigurationVector;
243         struct PluginData
244         {
245             friend class DebuggerManager;
246 
PluginDataPluginData247             PluginData() :  m_lastConfigID(-1) {}
248 
GetConfigurationsPluginData249             ConfigurationVector& GetConfigurations() { return m_configurations; }
GetConfigurationsPluginData250             const ConfigurationVector& GetConfigurations() const { return m_configurations; }
251 
252             cbDebuggerConfiguration* GetConfiguration(int index);
253 
ClearConfigurationsPluginData254             void ClearConfigurations()
255             {
256                 for (ConfigurationVector::iterator it = m_configurations.begin(); it != m_configurations.end(); ++it)
257                     delete *it;
258                 m_configurations.clear();
259             }
260         private:
261             ConfigurationVector m_configurations;
262             int m_lastConfigID;
263         };
264         typedef std::map<cbDebuggerPlugin*, PluginData> RegisteredPlugins;
265 
266     public:
267         /** Called to register a debugger plugin. It is called by cbDebuggerPlugin::OnAttach and it should not be called
268           *  by the debugger plugins explicitly in their OnAttachReal methods. */
269         bool RegisterDebugger(cbDebuggerPlugin *plugin);
270         /** Called to unregister a debugger plugin. It is called by cbDebuggerPlugin::OnRelease and it should not be
271           * called by the debugger plugins explicitly in their OnReleaseReal methods. */
272         bool UnregisterDebugger(cbDebuggerPlugin *plugin);
273 
274         ConfigManagerWrapper NewConfig(cbDebuggerPlugin *plugin, const wxString &name);
275         void RebuildAllConfigs();
276 
277         wxMenu* GetMenu();
278         bool HasMenu() const;
279         void BuildContextMenu(wxMenu &menu, const wxString& word_at_caret, bool is_running);
280 
281         TextCtrlLogger* GetLogger(int &index);
282         TextCtrlLogger* GetLogger();
283         void HideLogger();
284 
285     public: // debugger windows
286         void SetInterfaceFactory(cbDebugInterfaceFactory *factory);
287         cbDebugInterfaceFactory* GetInterfaceFactory();
288         void SetMenuHandler(cbDebuggerMenuHandler *handler);
289         cbDebuggerMenuHandler* GetMenuHandler();
290 
291         cbBacktraceDlg* GetBacktraceDialog();
292 
293         /** Returns a pointer to the breakpoints dialog.
294           * It will return nullptr if there are no debugger plugins loaded.
295           * Debugger plugin writers can treat it as always returning non-null value.
296           */
297         cbBreakpointsDlg* GetBreakpointDialog();
298 
299         /** Returns a pointer to the CPU registers dialog.
300           * It will return nullptr if there are no debugger plugins loaded.
301           * Debugger plugin writers can treat it as always returning non-null value.
302           */
303         cbCPURegistersDlg* GetCPURegistersDialog();
304 
305         /** Returns a pointer to the disassembly dialog.
306           * It will return nullptr if there are no debugger plugins loaded.
307           * Debugger plugin writers can treat it as always returning non-null value.
308           */
309         cbDisassemblyDlg* GetDisassemblyDialog();
310 
311         /** Returns a pointer to the memory dialog.
312           * It will return nullptr if there are no debugger plugins loaded.
313           * Debugger plugin writers can treat it as always returning non-null value.
314           */
315         cbExamineMemoryDlg* GetExamineMemoryDialog();
316 
317         /** Returns a pointer to the threads dialog.
318           * It will return nullptr if there are no debugger plugins loaded.
319           * Debugger plugin writers can treat it as always returning non-null value.
320           */
321         cbThreadsDlg* GetThreadsDialog();
322 
323         /** Returns a pointer to the watches dialog.
324           * It will return nullptr if there are no debugger plugins loaded.
325           * Debugger plugin writers can treat it as always returning non-null value.
326           */
327         cbWatchesDlg* GetWatchesDialog();
328 
329         bool ShowBacktraceDialog();
330 
331     public: // tests if something should be done
332         bool UpdateBacktrace();
333         bool UpdateCPURegisters();
334         bool UpdateDisassembly();
335         bool UpdateExamineMemory();
336         bool UpdateThreads();
337 
338     public: // watches
339         cbDebuggerPlugin* GetDebuggerHavingWatch(cb::shared_ptr<cbWatch> watch);
340         bool ShowValueTooltip(const cb::shared_ptr<cbWatch> &watch, const wxRect &rect);
341 
342         RegisteredPlugins const & GetAllDebuggers() const;
343         RegisteredPlugins & GetAllDebuggers();
344         cbDebuggerPlugin* GetActiveDebugger();
345         void SetActiveDebugger(cbDebuggerPlugin* activeDebugger, ConfigurationVector::const_iterator config);
346         void SetTargetsDefaultAsActiveDebugger();
347         bool IsActiveDebuggerTargetsDefault() const;
348 
349         bool IsDisassemblyMixedMode();
350         void SetDisassemblyMixedMode(bool mixed);
351 
352     private:
353         void ProcessSettings(RegisteredPlugins::iterator it);
354         void FindTargetsDebugger();
355         void RefreshUI();
356         void CreateWindows();
357         void DestoryWindows();
358 
359         void OnProjectActivated(CodeBlocksEvent& event);
360         void OnTargetSelected(CodeBlocksEvent& event);
361         void OnSettingsChanged(CodeBlocksEvent& event);
362         void OnPluginLoadingComplete(CodeBlocksEvent& event);
363     private:
364 
365         cbDebugInterfaceFactory *m_interfaceFactory;
366 
367         RegisteredPlugins m_registered;
368         cbDebuggerPlugin* m_activeDebugger;
369         cbDebuggerMenuHandler* m_menuHandler;
370 
371         cbBacktraceDlg* m_backtraceDialog;
372         cbBreakpointsDlg* m_breakPointsDialog;
373         cbCPURegistersDlg* m_cpuRegistersDialog;
374         cbDisassemblyDlg* m_disassemblyDialog;
375         cbExamineMemoryDlg* m_examineMemoryDialog;
376         cbThreadsDlg* m_threadsDialog;
377         cbWatchesDlg* m_watchesDialog;
378 
379         TextCtrlLogger* m_logger;
380         int m_loggerIndex;
381         bool m_isDisassemblyMixedMode;
382         bool m_useTargetsDefault;
383 };
384 
385 #endif // X_DEBUGGER_MANAGER_H
386 
387