1 //===-- SBProcess.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/API/SBProcess.h" 11 12 #include "lldb/lldb-defines.h" 13 #include "lldb/lldb-types.h" 14 15 #include "lldb/Interpreter/Args.h" 16 #include "lldb/Core/DataBufferHeap.h" 17 #include "lldb/Core/DataExtractor.h" 18 #include "lldb/Core/State.h" 19 #include "lldb/Core/Stream.h" 20 #include "lldb/Core/StreamFile.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/Thread.h" 25 26 // Project includes 27 28 #include "lldb/API/SBBroadcaster.h" 29 #include "lldb/API/SBDebugger.h" 30 #include "lldb/API/SBCommandReturnObject.h" 31 #include "lldb/API/SBEvent.h" 32 #include "lldb/API/SBThread.h" 33 #include "lldb/API/SBStringList.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 39 40 SBProcess::SBProcess () : 41 m_opaque_sp() 42 { 43 } 44 45 46 //---------------------------------------------------------------------- 47 // SBProcess constructor 48 //---------------------------------------------------------------------- 49 50 SBProcess::SBProcess (const SBProcess& rhs) : 51 m_opaque_sp (rhs.m_opaque_sp) 52 { 53 } 54 55 56 SBProcess::SBProcess (const lldb::ProcessSP &process_sp) : 57 m_opaque_sp (process_sp) 58 { 59 } 60 61 //---------------------------------------------------------------------- 62 // Destructor 63 //---------------------------------------------------------------------- 64 SBProcess::~SBProcess() 65 { 66 } 67 68 void 69 SBProcess::SetProcess (const ProcessSP &process_sp) 70 { 71 m_opaque_sp = process_sp; 72 } 73 74 void 75 SBProcess::Clear () 76 { 77 m_opaque_sp.reset(); 78 } 79 80 81 bool 82 SBProcess::IsValid() const 83 { 84 return m_opaque_sp.get() != NULL; 85 } 86 87 88 uint32_t 89 SBProcess::GetNumThreads () 90 { 91 if (m_opaque_sp) 92 { 93 const bool can_update = true; 94 return m_opaque_sp->GetThreadList().GetSize(can_update); 95 } 96 return 0; 97 } 98 99 SBThread 100 SBProcess::GetCurrentThread () const 101 { 102 SBThread sb_thread; 103 if (m_opaque_sp) 104 sb_thread.SetThread (m_opaque_sp->GetThreadList().GetCurrentThread()); 105 return sb_thread; 106 } 107 108 SBTarget 109 SBProcess::GetTarget() const 110 { 111 SBTarget sb_target; 112 if (m_opaque_sp) 113 sb_target = m_opaque_sp->GetTarget().GetSP(); 114 return sb_target; 115 } 116 117 118 size_t 119 SBProcess::PutSTDIN (const char *src, size_t src_len) 120 { 121 if (m_opaque_sp != NULL) 122 { 123 Error error; 124 return m_opaque_sp->PutSTDIN (src, src_len, error); 125 } 126 else 127 return 0; 128 } 129 130 size_t 131 SBProcess::GetSTDOUT (char *dst, size_t dst_len) const 132 { 133 if (m_opaque_sp != NULL) 134 { 135 Error error; 136 return m_opaque_sp->GetSTDOUT (dst, dst_len, error); 137 } 138 else 139 return 0; 140 } 141 142 size_t 143 SBProcess::GetSTDERR (char *dst, size_t dst_len) const 144 { 145 if (m_opaque_sp != NULL) 146 { 147 Error error; 148 return m_opaque_sp->GetSTDERR (dst, dst_len, error); 149 } 150 else 151 return 0; 152 } 153 154 void 155 SBProcess::ReportCurrentState (const SBEvent &event, FILE *out) const 156 { 157 if (out == NULL) 158 return; 159 160 if (m_opaque_sp != NULL) 161 { 162 const StateType event_state = SBProcess::GetStateFromEvent (event); 163 char message[1024]; 164 int message_len = ::snprintf (message, 165 sizeof (message), 166 "Process %d %s\n", 167 m_opaque_sp->GetID(), 168 SBDebugger::StateAsCString (event_state)); 169 170 if (message_len > 0) 171 ::fwrite (message, 1, message_len, out); 172 } 173 } 174 175 void 176 SBProcess::AppendCurrentStateReport (const SBEvent &event, SBCommandReturnObject &result) 177 { 178 if (m_opaque_sp != NULL) 179 { 180 const StateType event_state = SBProcess::GetStateFromEvent (event); 181 char message[1024]; 182 ::snprintf (message, 183 sizeof (message), 184 "Process %d %s\n", 185 m_opaque_sp->GetID(), 186 SBDebugger::StateAsCString (event_state)); 187 188 result.AppendMessage (message); 189 } 190 } 191 192 bool 193 SBProcess::SetCurrentThread (const SBThread &thread) 194 { 195 if (m_opaque_sp != NULL) 196 return m_opaque_sp->GetThreadList().SetCurrentThreadByID (thread.GetThreadID()); 197 return false; 198 } 199 200 bool 201 SBProcess::SetCurrentThreadByID (uint32_t tid) 202 { 203 if (m_opaque_sp != NULL) 204 return m_opaque_sp->GetThreadList().SetCurrentThreadByID (tid); 205 return false; 206 } 207 208 SBThread 209 SBProcess::GetThreadAtIndex (size_t index) 210 { 211 SBThread thread; 212 if (m_opaque_sp) 213 thread.SetThread (m_opaque_sp->GetThreadList().GetThreadAtIndex(index)); 214 return thread; 215 } 216 217 StateType 218 SBProcess::GetState () 219 { 220 if (m_opaque_sp != NULL) 221 return m_opaque_sp->GetState(); 222 else 223 return eStateInvalid; 224 } 225 226 227 int 228 SBProcess::GetExitStatus () 229 { 230 if (m_opaque_sp != NULL) 231 return m_opaque_sp->GetExitStatus (); 232 else 233 return 0; 234 } 235 236 const char * 237 SBProcess::GetExitDescription () 238 { 239 if (m_opaque_sp != NULL) 240 return m_opaque_sp->GetExitDescription (); 241 else 242 return NULL; 243 } 244 245 lldb::pid_t 246 SBProcess::GetProcessID () 247 { 248 if (m_opaque_sp) 249 return m_opaque_sp->GetID(); 250 else 251 return LLDB_INVALID_PROCESS_ID; 252 } 253 254 uint32_t 255 SBProcess::GetAddressByteSize () const 256 { 257 if (m_opaque_sp) 258 return m_opaque_sp->GetAddressByteSize(); 259 else 260 return 0; 261 } 262 263 bool 264 SBProcess::WaitUntilProcessHasStopped (SBCommandReturnObject &result) 265 { 266 bool state_changed = false; 267 268 if (IsValid()) 269 { 270 EventSP event_sp; 271 StateType state = m_opaque_sp->WaitForStateChangedEvents (NULL, event_sp); 272 273 while (StateIsStoppedState (state)) 274 { 275 state = m_opaque_sp->WaitForStateChangedEvents (NULL, event_sp); 276 SBEvent event (event_sp); 277 AppendCurrentStateReport (event, result); 278 state_changed = true; 279 } 280 } 281 return state_changed; 282 } 283 284 SBError 285 SBProcess::Continue () 286 { 287 SBError sb_error; 288 if (IsValid()) 289 sb_error.SetError(m_opaque_sp->Resume()); 290 else 291 sb_error.SetErrorString ("SBProcess is invalid"); 292 293 return sb_error; 294 } 295 296 297 SBError 298 SBProcess::Destroy () 299 { 300 SBError sb_error; 301 if (m_opaque_sp) 302 sb_error.SetError(m_opaque_sp->Destroy()); 303 else 304 sb_error.SetErrorString ("SBProcess is invalid"); 305 306 return sb_error; 307 } 308 309 310 SBError 311 SBProcess::Stop () 312 { 313 SBError sb_error; 314 if (IsValid()) 315 sb_error.SetError (m_opaque_sp->Halt()); 316 else 317 sb_error.SetErrorString ("SBProcess is invalid"); 318 return sb_error; 319 } 320 321 SBError 322 SBProcess::Kill () 323 { 324 SBError sb_error; 325 if (m_opaque_sp) 326 sb_error.SetError (m_opaque_sp->Destroy()); 327 else 328 sb_error.SetErrorString ("SBProcess is invalid"); 329 return sb_error; 330 } 331 332 333 SBError 334 SBProcess::AttachByName (const char *name, bool wait_for_launch) 335 { 336 SBError sb_error; 337 if (m_opaque_sp) 338 sb_error.SetError (m_opaque_sp->Attach (name, wait_for_launch)); 339 else 340 sb_error.SetErrorString ("SBProcess is invalid"); 341 return sb_error; 342 } 343 344 lldb::pid_t 345 SBProcess::AttachByPID (lldb::pid_t attach_pid) // DEPRECATED: will be removed in a few builds in favor of SBError AttachByPID(pid_t) 346 { 347 Attach (attach_pid); 348 return GetProcessID(); 349 } 350 351 352 SBError 353 SBProcess::Attach (lldb::pid_t attach_pid) 354 { 355 SBError sb_error; 356 if (m_opaque_sp) 357 sb_error.SetError (m_opaque_sp->Attach (attach_pid)); 358 else 359 sb_error.SetErrorString ("SBProcess is invalid"); 360 return sb_error; 361 } 362 363 SBError 364 SBProcess::Detach () 365 { 366 SBError sb_error; 367 if (m_opaque_sp) 368 sb_error.SetError (m_opaque_sp->Detach()); 369 else 370 sb_error.SetErrorString ("SBProcess is invalid"); 371 372 return sb_error; 373 } 374 375 SBError 376 SBProcess::Signal (int signal) 377 { 378 SBError sb_error; 379 if (m_opaque_sp) 380 sb_error.SetError (m_opaque_sp->Signal (signal)); 381 else 382 sb_error.SetErrorString ("SBProcess is invalid"); 383 return sb_error; 384 } 385 386 SBThread 387 SBProcess::GetThreadByID (tid_t sb_thread_id) 388 { 389 SBThread thread; 390 if (m_opaque_sp) 391 thread.SetThread (m_opaque_sp->GetThreadList().FindThreadByID ((tid_t) sb_thread_id)); 392 return thread; 393 } 394 395 StateType 396 SBProcess::GetStateFromEvent (const SBEvent &event) 397 { 398 return Process::ProcessEventData::GetStateFromEvent (event.get()); 399 } 400 401 bool 402 SBProcess::GetRestartedFromEvent (const SBEvent &event) 403 { 404 return Process::ProcessEventData::GetRestartedFromEvent (event.get()); 405 } 406 407 SBProcess 408 SBProcess::GetProcessFromEvent (const SBEvent &event) 409 { 410 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); 411 return process; 412 } 413 414 415 SBBroadcaster 416 SBProcess::GetBroadcaster () const 417 { 418 SBBroadcaster broadcaster(m_opaque_sp.get(), false); 419 return broadcaster; 420 } 421 422 lldb_private::Process * 423 SBProcess::operator->() const 424 { 425 return m_opaque_sp.get(); 426 } 427 428 size_t 429 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) 430 { 431 size_t bytes_read = 0; 432 433 if (IsValid()) 434 { 435 Error error; 436 bytes_read = m_opaque_sp->ReadMemory (addr, dst, dst_len, error); 437 sb_error.SetError (error); 438 } 439 else 440 { 441 sb_error.SetErrorString ("SBProcess is invalid"); 442 } 443 444 return bytes_read; 445 } 446 447 size_t 448 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) 449 { 450 size_t bytes_written = 0; 451 452 if (IsValid()) 453 { 454 Error error; 455 bytes_written = m_opaque_sp->WriteMemory (addr, src, src_len, error); 456 sb_error.SetError (error); 457 } 458 459 return bytes_written; 460 } 461 462 // Mimic shared pointer... 463 lldb_private::Process * 464 SBProcess::get() const 465 { 466 return m_opaque_sp.get(); 467 } 468 469