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