1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2013-2016, Rene Gollent, rene@gollent.com. 4 * Distributed under the terms of the MIT License. 5 */ 6 #ifndef TEAM_DEBUGGER_H 7 #define TEAM_DEBUGGER_H 8 9 10 #include <debugger.h> 11 #include <Looper.h> 12 13 #include "Team.h" 14 #include "TeamSettings.h" 15 #include "ThreadHandler.h" 16 #include "UserInterface.h" 17 #include "util/Worker.h" 18 19 20 class DebugEvent; 21 class DebuggerInterface; 22 class DebugReportGenerator; 23 class FileManager; 24 class ImageCreatedEvent; 25 class ImageDebugInfoLoadingState; 26 class ImageDeletedEvent; 27 class PostSyscallEvent; 28 class SettingsManager; 29 class TeamDebugInfo; 30 class TeamDeletedEvent; 31 class TeamExecEvent; 32 class TeamMemoryBlockManager; 33 class Thread; 34 class ThreadCreatedEvent; 35 class ThreadDeletedEvent; 36 class ThreadRenamedEvent; 37 class ThreadPriorityChangedEvent; 38 class WatchpointManager; 39 40 41 class TeamDebugger : public BLooper, private UserInterfaceListener, 42 private JobListener, private Team::Listener { 43 public: 44 class Listener; 45 46 public: 47 TeamDebugger(Listener* listener, 48 UserInterface* userInterface, 49 SettingsManager* settingsManager); 50 ~TeamDebugger(); 51 52 status_t Init(DebuggerInterface* interface, 53 thread_id threadID, int argc, 54 const char* const* argv, 55 bool stopInMain); 56 57 void Activate(); 58 TeamID()59 team_id TeamID() const { return fTeamID; } 60 IsPostMortem()61 bool IsPostMortem() const { return fIsPostMortem; } 62 ArgumentCount()63 int ArgumentCount() const 64 { return fCommandLineArgc; } Arguments()65 const char** Arguments() const 66 { return fCommandLineArgv; } GetSettingsManager()67 SettingsManager* GetSettingsManager() const 68 { return fSettingsManager; } GetUserInterface()69 UserInterface* GetUserInterface() const 70 { return fUserInterface; } 71 72 virtual void MessageReceived(BMessage* message); 73 74 private: 75 // UserInterfaceListener 76 virtual void FunctionSourceCodeRequested( 77 FunctionInstance* function, 78 bool forceDisassembly = false); 79 virtual void SourceEntryLocateRequested( 80 const char* sourcePath, 81 const char* locatedPath); 82 virtual void SourceEntryInvalidateRequested( 83 LocatableFile* sourceFile); 84 virtual void ImageDebugInfoRequested(Image* image); 85 virtual void ValueNodeValueRequested(CpuState* cpuState, 86 ValueNodeContainer* container, 87 ValueNode* valueNode); 88 virtual void ValueNodeWriteRequested(ValueNode* node, 89 CpuState* state, 90 Value* newValue); 91 virtual void ThreadActionRequested(thread_id threadID, 92 uint32 action, target_addr_t address); 93 94 virtual void SetBreakpointRequested(target_addr_t address, 95 bool enabled, bool hidden = false); 96 virtual void SetBreakpointEnabledRequested( 97 UserBreakpoint* breakpoint, 98 bool enabled); 99 virtual void SetBreakpointConditionRequested( 100 UserBreakpoint* breakpoint, 101 const char* condition); 102 virtual void ClearBreakpointConditionRequested( 103 UserBreakpoint* breakpoint); 104 virtual void ClearBreakpointRequested(target_addr_t address); 105 virtual void ClearBreakpointRequested( 106 UserBreakpoint* breakpoint); 107 108 virtual void SetStopOnImageLoadRequested(bool enabled, 109 bool useImageNames); 110 virtual void AddStopImageNameRequested( 111 const char* name); 112 virtual void RemoveStopImageNameRequested( 113 const char* name); 114 115 virtual void SetDefaultSignalDispositionRequested( 116 int32 disposition); 117 virtual void SetCustomSignalDispositionRequested( 118 int32 signal, int32 disposition); 119 virtual void RemoveCustomSignalDispositionRequested( 120 int32 signal); 121 122 virtual void SetWatchpointRequested(target_addr_t address, 123 uint32 type, int32 length, bool enabled); 124 virtual void SetWatchpointEnabledRequested( 125 Watchpoint *watchpoint, bool enabled); 126 virtual void ClearWatchpointRequested(target_addr_t address); 127 virtual void ClearWatchpointRequested( 128 Watchpoint* breakpoint); 129 130 virtual void InspectRequested(target_addr_t address, 131 TeamMemoryBlock::Listener* listener); 132 virtual void MemoryWriteRequested(target_addr_t address, 133 const void* data, target_size_t size); 134 135 virtual void ExpressionEvaluationRequested( 136 SourceLanguage* language, 137 ExpressionInfo* info, 138 StackFrame* frame = NULL, 139 ::Thread* thread = NULL); 140 141 virtual void DebugReportRequested(entry_ref* targetPath); 142 143 virtual void WriteCoreFileRequested(entry_ref* targetPath); 144 145 virtual void TeamRestartRequested(); 146 147 virtual bool UserInterfaceQuitRequested( 148 QuitOption quitOption); 149 150 // JobListener 151 virtual void JobStarted(Job* job); 152 virtual void JobDone(Job* job); 153 virtual void JobWaitingForInput(Job* job); 154 virtual void JobFailed(Job* job); 155 virtual void JobAborted(Job* job); 156 157 // Team::Listener 158 virtual void ThreadStateChanged( 159 const ::Team::ThreadEvent& event); 160 virtual void ThreadCpuStateChanged( 161 const ::Team::ThreadEvent& event); 162 virtual void ThreadStackTraceChanged( 163 const ::Team::ThreadEvent& event); 164 virtual void ImageDebugInfoChanged( 165 const ::Team::ImageEvent& event); 166 167 private: 168 struct ImageHandler; 169 struct ImageHandlerHashDefinition; 170 struct ImageInfoPendingThread; 171 struct ImageInfoPendingThreadHashDefinition; 172 173 typedef BOpenHashTable<ImageHandlerHashDefinition> ImageHandlerTable; 174 typedef BOpenHashTable<ImageInfoPendingThreadHashDefinition> 175 ImageInfoPendingThreadTable; 176 177 private: 178 static status_t _DebugEventListenerEntry(void* data); 179 status_t _DebugEventListener(); 180 181 void _HandleDebuggerMessage(DebugEvent* event); 182 183 bool _HandleTeamDeleted( 184 TeamDeletedEvent* event); 185 bool _HandleThreadCreated( 186 ThreadCreatedEvent* event); 187 bool _HandleThreadRenamed( 188 ThreadRenamedEvent* event); 189 bool _HandleThreadPriorityChanged( 190 ThreadPriorityChangedEvent* event); 191 bool _HandleThreadDeleted( 192 ThreadDeletedEvent* event); 193 bool _HandleImageCreated( 194 ImageCreatedEvent* event); 195 bool _HandleImageDeleted( 196 ImageDeletedEvent* event); 197 bool _HandlePostSyscall( 198 PostSyscallEvent* event); 199 200 void _PrepareForTeamExec(TeamExecEvent* event); 201 202 void _HandleImageDebugInfoChanged(image_id imageID); 203 void _HandleImageFileChanged(image_id imageID); 204 205 void _HandleSetUserBreakpoint(target_addr_t address, 206 bool enabled, bool hidden); 207 void _HandleSetUserBreakpoint( 208 UserBreakpoint* breakpoint, bool enabled); 209 void _HandleClearUserBreakpoint( 210 target_addr_t address); 211 void _HandleClearUserBreakpoint( 212 UserBreakpoint* breakpoint); 213 214 void _HandleSetWatchpoint(target_addr_t address, 215 uint32 type, int32 length, bool enabled); 216 void _HandleSetWatchpoint( 217 Watchpoint* watchpoint, bool enabled); 218 void _HandleClearWatchpoint( target_addr_t address); 219 void _HandleClearWatchpoint(Watchpoint* watchpoint); 220 221 void _HandleInspectAddress( 222 target_addr_t address, 223 TeamMemoryBlock::Listener* listener); 224 void _HandleWriteMemory( 225 target_addr_t address, void* data, 226 target_size_t size); 227 228 void _HandleEvaluateExpression( 229 SourceLanguage* language, 230 ExpressionInfo* info, 231 StackFrame* frame, 232 ::Thread* thread); 233 234 void _HandleWriteCoreFile(const entry_ref& ref); 235 236 status_t _HandleSetArguments(int argc, 237 const char* const* argv); 238 239 void _HandleDebugInfoJobUserInput( 240 ImageDebugInfoLoadingState* state); 241 242 ThreadHandler* _GetThreadHandler(thread_id threadID); 243 244 status_t _AddImage(const ImageInfo& imageInfo, 245 Image** _image = NULL); 246 247 void _LoadSettings(); 248 void _SaveSettings(); 249 250 void _NotifyUser(const char* title, 251 const char* text,...); 252 253 void _ResetUserBackgroundStatusIfNeeded(); 254 // updates user interface to 255 // ready/completed message 256 // for background work status 257 258 private: 259 Listener* fListener; 260 SettingsManager* fSettingsManager; 261 ::Team* fTeam; 262 team_id fTeamID; 263 bool fIsPostMortem; 264 ThreadHandlerTable fThreadHandlers; 265 // protected by the team lock 266 ImageHandlerTable* fImageHandlers; 267 ImageInfoPendingThreadTable* fImageInfoPendingThreads; 268 DebuggerInterface* fDebuggerInterface; 269 TeamDebugInfo* fTeamDebugInfo; 270 FileManager* fFileManager; 271 Worker* fWorker; 272 BreakpointManager* fBreakpointManager; 273 WatchpointManager* fWatchpointManager; 274 TeamMemoryBlockManager* 275 fMemoryBlockManager; 276 DebugReportGenerator* 277 fReportGenerator; 278 thread_id fDebugEventListener; 279 UserInterface* fUserInterface; 280 volatile bool fTerminating; 281 bool fKillTeamOnQuit; 282 TeamSettings fTeamSettings; 283 int fCommandLineArgc; 284 const char** fCommandLineArgv; 285 bool fExecPending; 286 }; 287 288 289 class TeamDebugger::Listener { 290 public: 291 virtual ~Listener(); 292 293 virtual void TeamDebuggerStarted(TeamDebugger* debugger) = 0; 294 virtual void TeamDebuggerRestartRequested( 295 TeamDebugger* debugger) = 0; 296 virtual void TeamDebuggerQuit(TeamDebugger* debugger) = 0; 297 }; 298 299 300 #endif // TEAM_DEBUGGER_H 301