SBProcess.cpp revision c833295baeec641086f536e78050388af36784f8
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 35using namespace lldb; 36using namespace lldb_private; 37 38 39 40SBProcess::SBProcess () : 41 m_opaque_sp() 42{ 43} 44 45 46//---------------------------------------------------------------------- 47// SBProcess constructor 48//---------------------------------------------------------------------- 49 50SBProcess::SBProcess (const SBProcess& rhs) : 51 m_opaque_sp (rhs.m_opaque_sp) 52{ 53} 54 55 56SBProcess::SBProcess (const lldb::ProcessSP &process_sp) : 57 m_opaque_sp (process_sp) 58{ 59} 60 61//---------------------------------------------------------------------- 62// Destructor 63//---------------------------------------------------------------------- 64SBProcess::~SBProcess() 65{ 66} 67 68void 69SBProcess::SetProcess (const ProcessSP &process_sp) 70{ 71 m_opaque_sp = process_sp; 72} 73 74void 75SBProcess::Clear () 76{ 77 m_opaque_sp.reset(); 78} 79 80 81bool 82SBProcess::IsValid() const 83{ 84 return m_opaque_sp.get() != NULL; 85} 86 87 88uint32_t 89SBProcess::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 99SBThread 100SBProcess::GetSelectedThread () const 101{ 102 SBThread sb_thread; 103 if (m_opaque_sp) 104 sb_thread.SetThread (m_opaque_sp->GetThreadList().GetSelectedThread()); 105 return sb_thread; 106} 107 108SBTarget 109SBProcess::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 118size_t 119SBProcess::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 130size_t 131SBProcess::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 142size_t 143SBProcess::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 154void 155SBProcess::ReportEventState (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 175void 176SBProcess::AppendEventStateReport (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 192bool 193SBProcess::SetSelectedThread (const SBThread &thread) 194{ 195 if (m_opaque_sp != NULL) 196 return m_opaque_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID()); 197 return false; 198} 199 200bool 201SBProcess::SetSelectedThreadByID (uint32_t tid) 202{ 203 if (m_opaque_sp != NULL) 204 return m_opaque_sp->GetThreadList().SetSelectedThreadByID (tid); 205 return false; 206} 207 208SBThread 209SBProcess::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 217StateType 218SBProcess::GetState () 219{ 220 if (m_opaque_sp != NULL) 221 return m_opaque_sp->GetState(); 222 else 223 return eStateInvalid; 224} 225 226 227int 228SBProcess::GetExitStatus () 229{ 230 if (m_opaque_sp != NULL) 231 return m_opaque_sp->GetExitStatus (); 232 else 233 return 0; 234} 235 236const char * 237SBProcess::GetExitDescription () 238{ 239 if (m_opaque_sp != NULL) 240 return m_opaque_sp->GetExitDescription (); 241 else 242 return NULL; 243} 244 245lldb::pid_t 246SBProcess::GetProcessID () 247{ 248 if (m_opaque_sp) 249 return m_opaque_sp->GetID(); 250 else 251 return LLDB_INVALID_PROCESS_ID; 252} 253 254uint32_t 255SBProcess::GetAddressByteSize () const 256{ 257 if (m_opaque_sp) 258 return m_opaque_sp->GetAddressByteSize(); 259 else 260 return 0; 261} 262 263bool 264SBProcess::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 AppendEventStateReport (event, result); 278 state_changed = true; 279 } 280 } 281 return state_changed; 282} 283 284SBError 285SBProcess::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 297SBError 298SBProcess::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 310SBError 311SBProcess::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 321SBError 322SBProcess::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 333SBError 334SBProcess::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 344lldb::pid_t 345SBProcess::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 352SBError 353SBProcess::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 363SBError 364SBProcess::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 375SBError 376SBProcess::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 386SBThread 387SBProcess::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 395StateType 396SBProcess::GetStateFromEvent (const SBEvent &event) 397{ 398 return Process::ProcessEventData::GetStateFromEvent (event.get()); 399} 400 401bool 402SBProcess::GetRestartedFromEvent (const SBEvent &event) 403{ 404 return Process::ProcessEventData::GetRestartedFromEvent (event.get()); 405} 406 407SBProcess 408SBProcess::GetProcessFromEvent (const SBEvent &event) 409{ 410 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); 411 return process; 412} 413 414 415SBBroadcaster 416SBProcess::GetBroadcaster () const 417{ 418 SBBroadcaster broadcaster(m_opaque_sp.get(), false); 419 return broadcaster; 420} 421 422lldb_private::Process * 423SBProcess::operator->() const 424{ 425 return m_opaque_sp.get(); 426} 427 428size_t 429SBProcess::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 447size_t 448SBProcess::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... 463lldb_private::Process * 464SBProcess::get() const 465{ 466 return m_opaque_sp.get(); 467} 468 469