1 //===-- SBThread.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/SBThread.h" 11 12 #include "lldb/API/SBSymbolContext.h" 13 #include "lldb/API/SBFileSpec.h" 14 #include "lldb/API/SBStream.h" 15 #include "lldb/Core/Debugger.h" 16 #include "lldb/Core/Stream.h" 17 #include "lldb/Core/StreamFile.h" 18 #include "lldb/Interpreter/CommandInterpreter.h" 19 #include "lldb/Target/Thread.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Symbol/SymbolContext.h" 22 #include "lldb/Symbol/CompileUnit.h" 23 #include "lldb/Target/StopInfo.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/ThreadPlan.h" 26 #include "lldb/Target/ThreadPlanStepInstruction.h" 27 #include "lldb/Target/ThreadPlanStepOut.h" 28 #include "lldb/Target/ThreadPlanStepRange.h" 29 #include "lldb/Target/ThreadPlanStepInRange.h" 30 31 32 #include "lldb/API/SBAddress.h" 33 #include "lldb/API/SBFrame.h" 34 #include "lldb/API/SBSourceManager.h" 35 #include "lldb/API/SBDebugger.h" 36 #include "lldb/API/SBProcess.h" 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 SBThread::SBThread () : 42 m_opaque_sp () 43 { 44 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE); 45 46 if (log) 47 log->Printf ("SBThread::SBThread () ==> this = %p", this); 48 } 49 50 //---------------------------------------------------------------------- 51 // Thread constructor 52 //---------------------------------------------------------------------- 53 SBThread::SBThread (const ThreadSP& lldb_object_sp) : 54 m_opaque_sp (lldb_object_sp) 55 { 56 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE); 57 58 if (log) 59 log->Printf ("SBThread::SBThread (const ThreadSP &lldb_object_sp) lldb_object_sp.get() = %p ==> this = %p", 60 lldb_object_sp.get(), this); 61 } 62 63 SBThread::SBThread (const SBThread &rhs) 64 { 65 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE); 66 67 if (log) 68 log->Printf ("SBThread::SBThread (const SBThread &rhs) rhs.m_opaque_sp.get() = %p ==> this = %p", 69 rhs.m_opaque_sp.get(), this); 70 71 m_opaque_sp = rhs.m_opaque_sp; 72 } 73 74 //---------------------------------------------------------------------- 75 // Destructor 76 //---------------------------------------------------------------------- 77 SBThread::~SBThread() 78 { 79 } 80 81 bool 82 SBThread::IsValid() const 83 { 84 return m_opaque_sp != NULL; 85 } 86 87 void 88 SBThread::Clear () 89 { 90 m_opaque_sp.reset(); 91 } 92 93 94 StopReason 95 SBThread::GetStopReason() 96 { 97 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 98 99 if (log) 100 log->Printf ("SBThread::GetStopReason ()"); 101 102 StopReason reason = eStopReasonInvalid; 103 if (m_opaque_sp) 104 { 105 StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 106 if (stop_info_sp) 107 reason = stop_info_sp->GetStopReason(); 108 } 109 110 if (log) 111 log->Printf ("SBThread::GetStopReason ==> %s", Thread::StopReasonAsCString (reason)); 112 113 return reason; 114 } 115 116 size_t 117 SBThread::GetStopDescription (char *dst, size_t dst_len) 118 { 119 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 120 121 if (log) 122 log->Printf ("SBThread::GetStopDescription (char *dst, size_t dst_len)"); 123 124 if (m_opaque_sp) 125 { 126 StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 127 if (stop_info_sp) 128 { 129 const char *stop_desc = stop_info_sp->GetDescription(); 130 if (stop_desc) 131 { 132 if (log) 133 log->Printf ("SBThread::GetStopDescription ==> %s", stop_desc); 134 if (dst) 135 return ::snprintf (dst, dst_len, "%s", stop_desc); 136 else 137 { 138 // NULL dst passed in, return the length needed to contain the description 139 return ::strlen (stop_desc) + 1; // Include the NULL byte for size 140 } 141 } 142 else 143 { 144 size_t stop_desc_len = 0; 145 switch (stop_info_sp->GetStopReason()) 146 { 147 case eStopReasonTrace: 148 case eStopReasonPlanComplete: 149 { 150 static char trace_desc[] = "step"; 151 stop_desc = trace_desc; 152 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 153 } 154 break; 155 156 case eStopReasonBreakpoint: 157 { 158 static char bp_desc[] = "breakpoint hit"; 159 stop_desc = bp_desc; 160 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 161 } 162 break; 163 164 case eStopReasonWatchpoint: 165 { 166 static char wp_desc[] = "watchpoint hit"; 167 stop_desc = wp_desc; 168 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 169 } 170 break; 171 172 case eStopReasonSignal: 173 { 174 stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 175 if (stop_desc == NULL || stop_desc[0] == '\0') 176 { 177 static char signal_desc[] = "signal"; 178 stop_desc = signal_desc; 179 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 180 } 181 } 182 break; 183 184 case eStopReasonException: 185 { 186 char exc_desc[] = "exception"; 187 stop_desc = exc_desc; 188 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 189 } 190 break; 191 192 default: 193 break; 194 } 195 196 if (stop_desc && stop_desc[0]) 197 { 198 if (log) 199 log->Printf ("SBThread::GetStopDescription ==> %s", stop_desc); 200 201 if (dst) 202 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 203 204 if (stop_desc_len == 0) 205 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 206 207 return stop_desc_len; 208 } 209 } 210 } 211 } 212 if (dst) 213 *dst = 0; 214 return 0; 215 } 216 217 void 218 SBThread::SetThread (const ThreadSP& lldb_object_sp) 219 { 220 m_opaque_sp = lldb_object_sp; 221 } 222 223 224 lldb::tid_t 225 SBThread::GetThreadID () const 226 { 227 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 228 229 if (log) 230 log->Printf ("SBThread::GetThreadID()"); 231 232 lldb::tid_t id = LLDB_INVALID_THREAD_ID; 233 if (m_opaque_sp) 234 id = m_opaque_sp->GetID(); 235 236 if (log) 237 log->Printf ("SBThread::GetThreadID ==> %d", id); 238 239 return id; 240 } 241 242 uint32_t 243 SBThread::GetIndexID () const 244 { 245 if (m_opaque_sp) 246 return m_opaque_sp->GetIndexID(); 247 return LLDB_INVALID_INDEX32; 248 } 249 const char * 250 SBThread::GetName () const 251 { 252 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 253 254 if (log) 255 log->Printf ("SBThread::GetName ()"); 256 257 if (m_opaque_sp) 258 { 259 if (log) 260 log->Printf ("SBThread::GetName ==> %s", m_opaque_sp->GetName()); 261 return m_opaque_sp->GetName(); 262 } 263 264 if (log) 265 log->Printf ("SBThread::GetName ==> NULL"); 266 267 return NULL; 268 } 269 270 const char * 271 SBThread::GetQueueName () const 272 { 273 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 274 275 if (log) 276 log->Printf ("SBThread::GetQueueName ()"); 277 278 if (m_opaque_sp) 279 { 280 if (log) 281 log->Printf ("SBThread::GetQueueName ==> %s", m_opaque_sp->GetQueueName()); 282 return m_opaque_sp->GetQueueName(); 283 } 284 285 if (log) 286 log->Printf ("SBThread::GetQueueName ==> NULL"); 287 288 return NULL; 289 } 290 291 292 void 293 SBThread::StepOver (lldb::RunMode stop_other_threads) 294 { 295 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 296 297 if (log) 298 log->Printf ("SBThread::StepOver (lldb::RunMode stop_other_threads) stop_other_threads = %s)", 299 Thread::RunModeAsCString (stop_other_threads)); 300 301 if (m_opaque_sp) 302 { 303 bool abort_other_plans = true; 304 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0)); 305 306 if (frame_sp) 307 { 308 if (frame_sp->HasDebugInformation ()) 309 { 310 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 311 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans, 312 eStepTypeOver, 313 sc.line_entry.range, 314 sc, 315 stop_other_threads, 316 false); 317 318 } 319 else 320 { 321 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true, 322 abort_other_plans, 323 stop_other_threads); 324 } 325 } 326 327 Process &process = m_opaque_sp->GetProcess(); 328 // Why do we need to set the current thread by ID here??? 329 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 330 Error error (process.Resume()); 331 if (error.Success()) 332 { 333 // If we are doing synchronous mode, then wait for the 334 // process to stop yet again! 335 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 336 process.WaitForProcessToStop (NULL); 337 } 338 } 339 } 340 341 void 342 SBThread::StepInto (lldb::RunMode stop_other_threads) 343 { 344 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 345 346 if (log) 347 log->Printf ("SBThread::StepInto (lldb::RunMode stop_other_threads) stop_other_threads =%s", 348 Thread::RunModeAsCString (stop_other_threads)); 349 350 if (m_opaque_sp) 351 { 352 bool abort_other_plans = true; 353 354 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0)); 355 356 if (frame_sp && frame_sp->HasDebugInformation ()) 357 { 358 bool avoid_code_without_debug_info = true; 359 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 360 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans, 361 eStepTypeInto, 362 sc.line_entry.range, 363 sc, 364 stop_other_threads, 365 avoid_code_without_debug_info); 366 } 367 else 368 { 369 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false, 370 abort_other_plans, 371 stop_other_threads); 372 } 373 374 Process &process = m_opaque_sp->GetProcess(); 375 // Why do we need to set the current thread by ID here??? 376 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 377 Error error (process.Resume()); 378 if (error.Success()) 379 { 380 // If we are doing synchronous mode, then wait for the 381 // process to stop yet again! 382 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 383 process.WaitForProcessToStop (NULL); 384 } 385 } 386 } 387 388 void 389 SBThread::StepOut () 390 { 391 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 392 393 if (log) 394 log->Printf ("SBThread::StepOut ()"); 395 396 if (m_opaque_sp) 397 { 398 bool abort_other_plans = true; 399 bool stop_other_threads = true; 400 401 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion); 402 403 Process &process = m_opaque_sp->GetProcess(); 404 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 405 Error error (process.Resume()); 406 if (error.Success()) 407 { 408 // If we are doing synchronous mode, then wait for the 409 // process to stop yet again! 410 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 411 process.WaitForProcessToStop (NULL); 412 } 413 } 414 } 415 416 void 417 SBThread::StepInstruction (bool step_over) 418 { 419 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 420 421 if (log) 422 log->Printf ("SBThread::StepInstruction (bool step_over) step_over = %s", (step_over ? "true" : "false")); 423 424 if (m_opaque_sp) 425 { 426 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 427 Process &process = m_opaque_sp->GetProcess(); 428 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 429 Error error (process.Resume()); 430 if (error.Success()) 431 { 432 // If we are doing synchronous mode, then wait for the 433 // process to stop yet again! 434 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 435 process.WaitForProcessToStop (NULL); 436 } 437 } 438 } 439 440 void 441 SBThread::RunToAddress (lldb::addr_t addr) 442 { 443 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 444 445 if (log) 446 log->Printf ("SBThread::RunToAddress (lldb:;addr_t addr) addr = %p", addr); 447 448 if (m_opaque_sp) 449 { 450 bool abort_other_plans = true; 451 bool stop_other_threads = true; 452 453 Address target_addr (NULL, addr); 454 455 m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 456 Process &process = m_opaque_sp->GetProcess(); 457 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 458 Error error (process.Resume()); 459 if (error.Success()) 460 { 461 // If we are doing synchronous mode, then wait for the 462 // process to stop yet again! 463 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 464 process.WaitForProcessToStop (NULL); 465 } 466 } 467 468 } 469 470 SBProcess 471 SBThread::GetProcess () 472 { 473 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 474 475 if (log) 476 log->Printf ("SBThread::GetProcess ()"); 477 478 SBProcess process; 479 if (m_opaque_sp) 480 { 481 // Have to go up to the target so we can get a shared pointer to our process... 482 process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP()); 483 } 484 485 if (log) 486 { 487 SBStream sstr; 488 process.GetDescription (sstr); 489 log->Printf ("SBThread::GetProcess ==> SBProcess (this = %p, '%s')", &process, sstr.GetData()); 490 } 491 492 return process; 493 } 494 495 uint32_t 496 SBThread::GetNumFrames () 497 { 498 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 499 500 if (log) 501 log->Printf ("SBThread::GetNumFrames ()"); 502 503 uint32_t num_frames = 0; 504 if (m_opaque_sp) 505 num_frames = m_opaque_sp->GetStackFrameCount(); 506 507 if (log) 508 log->Printf ("SBThread::GetNumFrames ==> %d", num_frames); 509 510 return num_frames; 511 } 512 513 SBFrame 514 SBThread::GetFrameAtIndex (uint32_t idx) 515 { 516 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 517 518 if (log) 519 log->Printf ("SBThread::GetFrameAtIndex (uint32_t idx) idx = %d", idx); 520 521 SBFrame sb_frame; 522 if (m_opaque_sp) 523 sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx)); 524 525 if (log) 526 { 527 SBStream sstr; 528 sb_frame.GetDescription (sstr); 529 log->Printf ("SBThread::GetFrameAtIndex ==> SBFrame (this = %p, '%s')", &sb_frame, sstr.GetData()); 530 } 531 532 return sb_frame; 533 } 534 535 const lldb::SBThread & 536 SBThread::operator = (const lldb::SBThread &rhs) 537 { 538 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 539 540 if (log) 541 log->Printf ("SBThread::operator= (const lldb::SBThread &rhs) rhs.m_opaque_sp.get() = %p ==> this = %p", 542 rhs.m_opaque_sp.get(), this); 543 544 m_opaque_sp = rhs.m_opaque_sp; 545 return *this; 546 } 547 548 bool 549 SBThread::operator == (const SBThread &rhs) const 550 { 551 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 552 } 553 554 bool 555 SBThread::operator != (const SBThread &rhs) const 556 { 557 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 558 } 559 560 lldb_private::Thread * 561 SBThread::GetLLDBObjectPtr () 562 { 563 return m_opaque_sp.get(); 564 } 565 566 const lldb_private::Thread * 567 SBThread::operator->() const 568 { 569 return m_opaque_sp.get(); 570 } 571 572 const lldb_private::Thread & 573 SBThread::operator*() const 574 { 575 return *m_opaque_sp; 576 } 577 578 lldb_private::Thread * 579 SBThread::operator->() 580 { 581 return m_opaque_sp.get(); 582 } 583 584 lldb_private::Thread & 585 SBThread::operator*() 586 { 587 return *m_opaque_sp; 588 } 589 590 bool 591 SBThread::GetDescription (SBStream &description) 592 { 593 if (m_opaque_sp) 594 { 595 StreamString strm; 596 description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID()); 597 } 598 else 599 description.Printf ("No value"); 600 601 return true; 602 } 603 604 bool 605 SBThread::GetDescription (SBStream &description) const 606 { 607 if (m_opaque_sp) 608 { 609 StreamString strm; 610 description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID()); 611 } 612 else 613 description.Printf ("No value"); 614 615 return true; 616 } 617