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