1 //===-- StopInfo.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/Target/StopInfo.h" 11 12 // C Includes 13 // C++ Includes 14 #include <string> 15 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Core/Log.h" 19 #include "lldb/Breakpoint/Breakpoint.h" 20 #include "lldb/Breakpoint/BreakpointLocation.h" 21 #include "lldb/Breakpoint/StoppointCallbackContext.h" 22 #include "lldb/Breakpoint/Watchpoint.h" 23 #include "lldb/Core/Debugger.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Expression/ClangUserExpression.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/Thread.h" 28 #include "lldb/Target/ThreadPlan.h" 29 #include "lldb/Target/Process.h" 30 #include "lldb/Target/UnixSignals.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 StopInfo::StopInfo (Thread &thread, uint64_t value) : 36 m_thread (thread), 37 m_stop_id (thread.GetProcess()->GetStopID()), 38 m_resume_id (thread.GetProcess()->GetResumeID()), 39 m_value (value) 40 { 41 } 42 43 bool 44 StopInfo::IsValid () const 45 { 46 return m_thread.GetProcess()->GetStopID() == m_stop_id; 47 } 48 49 void 50 StopInfo::MakeStopInfoValid () 51 { 52 m_stop_id = m_thread.GetProcess()->GetStopID(); 53 m_resume_id = m_thread.GetProcess()->GetResumeID(); 54 } 55 56 bool 57 StopInfo::HasTargetRunSinceMe () 58 { 59 lldb::StateType ret_type = m_thread.GetProcess()->GetPrivateState(); 60 if (ret_type == eStateRunning) 61 { 62 return true; 63 } 64 else if (ret_type == eStateStopped) 65 { 66 // This is a little tricky. We want to count "run and stopped again before you could 67 // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we don't want to 68 // include any running of the target done for expressions. So we track both resumes, 69 // and resumes caused by expressions, and check if there are any resumes NOT caused 70 // by expressions. 71 72 uint32_t curr_resume_id = m_thread.GetProcess()->GetResumeID(); 73 uint32_t last_user_expression_id = m_thread.GetProcess()->GetLastUserExpressionResumeID (); 74 if (curr_resume_id == m_resume_id) 75 { 76 return false; 77 } 78 else if (curr_resume_id > last_user_expression_id) 79 { 80 return true; 81 } 82 } 83 return false; 84 } 85 86 //---------------------------------------------------------------------- 87 // StopInfoBreakpoint 88 //---------------------------------------------------------------------- 89 90 namespace lldb_private 91 { 92 class StopInfoBreakpoint : public StopInfo 93 { 94 public: 95 96 StopInfoBreakpoint (Thread &thread, break_id_t break_id) : 97 StopInfo (thread, break_id), 98 m_description(), 99 m_should_stop (false), 100 m_should_stop_is_valid (false), 101 m_should_perform_action (true), 102 m_address (LLDB_INVALID_ADDRESS) 103 { 104 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 105 if (bp_site_sp) 106 { 107 m_address = bp_site_sp->GetLoadAddress(); 108 } 109 } 110 111 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) : 112 StopInfo (thread, break_id), 113 m_description(), 114 m_should_stop (should_stop), 115 m_should_stop_is_valid (true), 116 m_should_perform_action (true), 117 m_address (LLDB_INVALID_ADDRESS) 118 { 119 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 120 if (bp_site_sp) 121 { 122 m_address = bp_site_sp->GetLoadAddress(); 123 } 124 } 125 126 virtual ~StopInfoBreakpoint () 127 { 128 } 129 130 virtual StopReason 131 GetStopReason () const 132 { 133 return eStopReasonBreakpoint; 134 } 135 136 virtual bool 137 ShouldStopSynchronous (Event *event_ptr) 138 { 139 if (!m_should_stop_is_valid) 140 { 141 // Only check once if we should stop at a breakpoint 142 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 143 if (bp_site_sp) 144 { 145 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 146 StoppointCallbackContext context (event_ptr, exe_ctx, true); 147 m_should_stop = bp_site_sp->ShouldStop (&context); 148 } 149 else 150 { 151 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 152 153 if (log) 154 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); 155 156 m_should_stop = true; 157 } 158 m_should_stop_is_valid = true; 159 } 160 return m_should_stop; 161 } 162 163 bool 164 ShouldStop (Event *event_ptr) 165 { 166 // This just reports the work done by PerformAction or the synchronous stop. It should 167 // only ever get called after they have had a chance to run. 168 assert (m_should_stop_is_valid); 169 return m_should_stop; 170 } 171 172 virtual void 173 PerformAction (Event *event_ptr) 174 { 175 if (!m_should_perform_action) 176 return; 177 m_should_perform_action = false; 178 179 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 180 181 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 182 183 if (bp_site_sp) 184 { 185 size_t num_owners = bp_site_sp->GetNumberOfOwners(); 186 187 if (num_owners == 0) 188 { 189 m_should_stop = true; 190 } 191 else 192 { 193 // We go through each location, and test first its condition. If the condition says to stop, 194 // then we run the callback for that location. If that callback says to stop as well, then 195 // we set m_should_stop to true; we are going to stop. 196 // But we still want to give all the breakpoints whose conditions say we are going to stop a 197 // chance to run their callbacks. 198 // Of course if any callback restarts the target by putting "continue" in the callback, then 199 // we're going to restart, without running the rest of the callbacks. And in this case we will 200 // end up not stopping even if another location said we should stop. But that's better than not 201 // running all the callbacks. 202 203 m_should_stop = false; 204 205 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 206 StoppointCallbackContext context (event_ptr, exe_ctx, false); 207 208 for (size_t j = 0; j < num_owners; j++) 209 { 210 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j); 211 212 // First run the condition for the breakpoint. If that says we should stop, then we'll run 213 // the callback for the breakpoint. If the callback says we shouldn't stop that will win. 214 215 bool condition_says_stop = true; 216 if (bp_loc_sp->GetConditionText() != NULL) 217 { 218 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 219 // constructor errors up to the debugger's Async I/O. 220 221 ValueObjectSP result_valobj_sp; 222 223 ExecutionResults result_code; 224 ValueObjectSP result_value_sp; 225 const bool discard_on_error = true; 226 Error error; 227 result_code = ClangUserExpression::EvaluateWithError (exe_ctx, 228 eExecutionPolicyOnlyWhenNeeded, 229 lldb::eLanguageTypeUnknown, 230 ClangUserExpression::eResultTypeAny, 231 discard_on_error, 232 bp_loc_sp->GetConditionText(), 233 NULL, 234 result_value_sp, 235 error); 236 if (result_code == eExecutionCompleted) 237 { 238 if (result_value_sp) 239 { 240 Scalar scalar_value; 241 if (result_value_sp->ResolveValue (scalar_value)) 242 { 243 if (scalar_value.ULongLong(1) == 0) 244 condition_says_stop = false; 245 else 246 condition_says_stop = true; 247 if (log) 248 log->Printf("Condition successfully evaluated, result is %s.\n", 249 m_should_stop ? "true" : "false"); 250 } 251 else 252 { 253 condition_says_stop = true; 254 if (log) 255 log->Printf("Failed to get an integer result from the expression."); 256 } 257 } 258 } 259 else 260 { 261 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 262 StreamSP error_sp = debugger.GetAsyncErrorStream (); 263 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint "); 264 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 265 error_sp->Printf (": \"%s\"", 266 bp_loc_sp->GetConditionText()); 267 error_sp->EOL(); 268 const char *err_str = error.AsCString("<Unknown Error>"); 269 if (log) 270 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 271 272 error_sp->PutCString (err_str); 273 error_sp->EOL(); 274 error_sp->Flush(); 275 // If the condition fails to be parsed or run, we should stop. 276 condition_says_stop = true; 277 } 278 } 279 280 // If this location's condition says we should aren't going to stop, 281 // then don't run the callback for this location. 282 if (!condition_says_stop) 283 continue; 284 285 bool callback_says_stop; 286 287 // FIXME: For now the callbacks have to run in async mode - the first time we restart we need 288 // to get out of there. So set it here. 289 // When we figure out how to nest breakpoint hits then this will change. 290 291 Debugger &debugger = m_thread.CalculateTarget()->GetDebugger(); 292 bool old_async = debugger.GetAsyncExecution(); 293 debugger.SetAsyncExecution (true); 294 295 callback_says_stop = bp_loc_sp->InvokeCallback (&context); 296 297 debugger.SetAsyncExecution (old_async); 298 299 if (callback_says_stop) 300 m_should_stop = true; 301 302 // Also make sure that the callback hasn't continued the target. 303 // If it did, when we'll set m_should_start to false and get out of here. 304 if (HasTargetRunSinceMe ()) 305 { 306 m_should_stop = false; 307 break; 308 } 309 } 310 } 311 // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again. 312 m_should_stop_is_valid = true; 313 314 } 315 else 316 { 317 m_should_stop = true; 318 m_should_stop_is_valid = true; 319 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 320 321 if (log) 322 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); 323 } 324 if (log) 325 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 326 } 327 328 virtual bool 329 ShouldNotify (Event *event_ptr) 330 { 331 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 332 if (bp_site_sp) 333 { 334 bool all_internal = true; 335 336 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++) 337 { 338 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) 339 { 340 all_internal = false; 341 break; 342 } 343 } 344 return all_internal == false; 345 } 346 return true; 347 } 348 349 virtual const char * 350 GetDescription () 351 { 352 if (m_description.empty()) 353 { 354 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 355 if (bp_site_sp) 356 { 357 StreamString strm; 358 strm.Printf("breakpoint "); 359 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief); 360 m_description.swap (strm.GetString()); 361 } 362 else 363 { 364 StreamString strm; 365 if (m_address == LLDB_INVALID_ADDRESS) 366 strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value); 367 else 368 strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address); 369 m_description.swap (strm.GetString()); 370 } 371 } 372 return m_description.c_str(); 373 } 374 375 private: 376 std::string m_description; 377 bool m_should_stop; 378 bool m_should_stop_is_valid; 379 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions 380 // etc. behind the users backs, we need to make sure we only REALLY perform the action once. 381 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo, 382 // in case somebody deletes it between the time the StopInfo is made and the 383 // description is asked for. 384 }; 385 386 387 //---------------------------------------------------------------------- 388 // StopInfoWatchpoint 389 //---------------------------------------------------------------------- 390 391 class StopInfoWatchpoint : public StopInfo 392 { 393 public: 394 395 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) : 396 StopInfo(thread, watch_id), 397 m_description(), 398 m_should_stop(false), 399 m_should_stop_is_valid(false) 400 { 401 } 402 403 virtual ~StopInfoWatchpoint () 404 { 405 } 406 407 virtual StopReason 408 GetStopReason () const 409 { 410 return eStopReasonWatchpoint; 411 } 412 413 virtual bool 414 ShouldStop (Event *event_ptr) 415 { 416 // ShouldStop() method is idempotent and should not affect hit count. 417 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent() 418 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()-> 419 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()-> 420 // StopInfoWatchpoint::ShouldStop() and 421 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()-> 422 // StopInfoWatchpoint::PerformAction(). 423 if (m_should_stop_is_valid) 424 return m_should_stop; 425 426 WatchpointSP wp_sp = 427 m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue()); 428 if (wp_sp) 429 { 430 // Check if we should stop at a watchpoint. 431 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 432 StoppointCallbackContext context (event_ptr, exe_ctx, true); 433 m_should_stop = wp_sp->ShouldStop (&context); 434 } 435 else 436 { 437 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 438 439 if (log) 440 log->Printf ("Process::%s could not find watchpoint location id: %lld...", 441 __FUNCTION__, GetValue()); 442 443 m_should_stop = true; 444 } 445 m_should_stop_is_valid = true; 446 return m_should_stop; 447 } 448 449 // Perform any action that is associated with this stop. This is done as the 450 // Event is removed from the event queue. 451 virtual void 452 PerformAction (Event *event_ptr) 453 { 454 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS); 455 // We're going to calculate if we should stop or not in some way during the course of 456 // this code. Also by default we're going to stop, so set that here. 457 m_should_stop = true; 458 459 WatchpointSP wp_sp = 460 m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue()); 461 if (wp_sp) 462 { 463 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 464 Process* process = exe_ctx.GetProcessPtr(); 465 { 466 // check if this process is running on an architecture where watchpoints trigger 467 // before the associated instruction runs. if so, disable the WP, single-step and then 468 // re-enable the watchpoint 469 if (process) 470 { 471 uint32_t num; bool wp_triggers_after; 472 if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success()) 473 { 474 if (!wp_triggers_after) 475 { 476 process->DisableWatchpoint(wp_sp.get()); 477 478 ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over 479 false, // abort_other_plans 480 true); // stop_other_threads 481 new_plan->SetIsMasterPlan (true); 482 new_plan->SetOkayToDiscard (false); 483 process->GetThreadList().SetSelectedThreadByID (m_thread.GetID()); 484 process->Resume (); 485 process->WaitForProcessToStop (NULL); 486 process->GetThreadList().SetSelectedThreadByID (m_thread.GetID()); 487 MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above 488 489 process->EnableWatchpoint(wp_sp.get()); 490 } 491 } 492 } 493 } 494 495 // Record the snapshot of our watchpoint. 496 VariableSP var_sp; 497 ValueObjectSP valobj_sp; 498 StackFrame *frame = exe_ctx.GetFramePtr(); 499 if (frame) 500 { 501 bool snapshot_taken = true; 502 if (!wp_sp->IsWatchVariable()) 503 { 504 // We are not watching a variable, just read from the process memory for the watched location. 505 assert (process); 506 Error error; 507 uint64_t val = process->ReadUnsignedIntegerFromMemory(wp_sp->GetLoadAddress(), 508 wp_sp->GetByteSize(), 509 0, 510 error); 511 if (log) 512 { 513 if (error.Success()) 514 log->Printf("Watchpoint snapshot val taken: 0x%llx\n", val); 515 else 516 log->Printf("Watchpoint snapshot val taking failed.\n"); 517 } 518 wp_sp->SetNewSnapshotVal(val); 519 } 520 else if (!wp_sp->GetWatchSpec().empty()) 521 { 522 // Use our frame to evaluate the variable expression. 523 Error error; 524 uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember | 525 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess; 526 valobj_sp = frame->GetValueForVariableExpressionPath (wp_sp->GetWatchSpec().c_str(), 527 eNoDynamicValues, 528 expr_path_options, 529 var_sp, 530 error); 531 if (valobj_sp) 532 { 533 // We're in business. 534 StreamString ss; 535 ValueObject::DumpValueObject(ss, valobj_sp.get()); 536 wp_sp->SetNewSnapshot(ss.GetString()); 537 } 538 else 539 { 540 // The variable expression has become out of scope? 541 // Let us forget about this stop info. 542 if (log) 543 log->Printf("Snapshot attempt failed. Variable expression has become out of scope?"); 544 snapshot_taken = false; 545 m_should_stop = false; 546 wp_sp->IncrementFalseAlarmsAndReviseHitCount(); 547 } 548 549 if (log && snapshot_taken) 550 log->Printf("Watchpoint snapshot taken: '%s'\n", wp_sp->GetNewSnapshot().c_str()); 551 } 552 553 // Now dump the snapshots we have taken. 554 if (snapshot_taken) 555 { 556 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 557 StreamSP output_sp = debugger.GetAsyncOutputStream (); 558 wp_sp->DumpSnapshots(output_sp.get()); 559 output_sp->EOL(); 560 output_sp->Flush(); 561 } 562 } 563 564 if (m_should_stop && wp_sp->GetConditionText() != NULL) 565 { 566 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 567 // constructor errors up to the debugger's Async I/O. 568 ExecutionResults result_code; 569 ValueObjectSP result_value_sp; 570 const bool discard_on_error = true; 571 Error error; 572 result_code = ClangUserExpression::EvaluateWithError (exe_ctx, 573 eExecutionPolicyAlways, 574 lldb::eLanguageTypeUnknown, 575 ClangUserExpression::eResultTypeAny, 576 discard_on_error, 577 wp_sp->GetConditionText(), 578 NULL, 579 result_value_sp, 580 error, 581 500000); 582 if (result_code == eExecutionCompleted) 583 { 584 if (result_value_sp) 585 { 586 Scalar scalar_value; 587 if (result_value_sp->ResolveValue (scalar_value)) 588 { 589 if (scalar_value.ULongLong(1) == 0) 590 { 591 // We have been vetoed. This takes precedence over querying 592 // the watchpoint whether it should stop (aka ignore count and 593 // friends). See also StopInfoWatchpoint::ShouldStop() as well 594 // as Process::ProcessEventData::DoOnRemoval(). 595 m_should_stop = false; 596 } 597 else 598 m_should_stop = true; 599 if (log) 600 log->Printf("Condition successfully evaluated, result is %s.\n", 601 m_should_stop ? "true" : "false"); 602 } 603 else 604 { 605 m_should_stop = true; 606 if (log) 607 log->Printf("Failed to get an integer result from the expression."); 608 } 609 } 610 } 611 else 612 { 613 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 614 StreamSP error_sp = debugger.GetAsyncErrorStream (); 615 error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint "); 616 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 617 error_sp->Printf (": \"%s\"", 618 wp_sp->GetConditionText()); 619 error_sp->EOL(); 620 const char *err_str = error.AsCString("<Unknown Error>"); 621 if (log) 622 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 623 624 error_sp->PutCString (err_str); 625 error_sp->EOL(); 626 error_sp->Flush(); 627 // If the condition fails to be parsed or run, we should stop. 628 m_should_stop = true; 629 } 630 } 631 632 // If the condition says to stop, we run the callback to further decide whether to stop. 633 if (m_should_stop) 634 { 635 StoppointCallbackContext context (event_ptr, exe_ctx, false); 636 bool stop_requested = wp_sp->InvokeCallback (&context); 637 // Also make sure that the callback hasn't continued the target. 638 // If it did, when we'll set m_should_stop to false and get out of here. 639 if (HasTargetRunSinceMe ()) 640 m_should_stop = false; 641 642 if (m_should_stop && !stop_requested) 643 { 644 // We have been vetoed by the callback mechanism. 645 m_should_stop = false; 646 } 647 } 648 } 649 else 650 { 651 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 652 653 if (log) 654 log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value); 655 } 656 if (log) 657 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 658 } 659 660 virtual const char * 661 GetDescription () 662 { 663 if (m_description.empty()) 664 { 665 StreamString strm; 666 strm.Printf("watchpoint %lli", m_value); 667 m_description.swap (strm.GetString()); 668 } 669 return m_description.c_str(); 670 } 671 672 private: 673 std::string m_description; 674 bool m_should_stop; 675 bool m_should_stop_is_valid; 676 }; 677 678 679 680 //---------------------------------------------------------------------- 681 // StopInfoUnixSignal 682 //---------------------------------------------------------------------- 683 684 class StopInfoUnixSignal : public StopInfo 685 { 686 public: 687 688 StopInfoUnixSignal (Thread &thread, int signo) : 689 StopInfo (thread, signo) 690 { 691 } 692 693 virtual ~StopInfoUnixSignal () 694 { 695 } 696 697 698 virtual StopReason 699 GetStopReason () const 700 { 701 return eStopReasonSignal; 702 } 703 704 virtual bool 705 ShouldStop (Event *event_ptr) 706 { 707 return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value); 708 } 709 710 711 // If should stop returns false, check if we should notify of this event 712 virtual bool 713 ShouldNotify (Event *event_ptr) 714 { 715 return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value); 716 } 717 718 719 virtual void 720 WillResume (lldb::StateType resume_state) 721 { 722 if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false) 723 m_thread.SetResumeSignal(m_value); 724 } 725 726 virtual const char * 727 GetDescription () 728 { 729 if (m_description.empty()) 730 { 731 StreamString strm; 732 const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value); 733 if (signal_name) 734 strm.Printf("signal %s", signal_name); 735 else 736 strm.Printf("signal %lli", m_value); 737 m_description.swap (strm.GetString()); 738 } 739 return m_description.c_str(); 740 } 741 }; 742 743 //---------------------------------------------------------------------- 744 // StopInfoTrace 745 //---------------------------------------------------------------------- 746 747 class StopInfoTrace : public StopInfo 748 { 749 public: 750 751 StopInfoTrace (Thread &thread) : 752 StopInfo (thread, LLDB_INVALID_UID) 753 { 754 } 755 756 virtual ~StopInfoTrace () 757 { 758 } 759 760 virtual StopReason 761 GetStopReason () const 762 { 763 return eStopReasonTrace; 764 } 765 766 virtual const char * 767 GetDescription () 768 { 769 if (m_description.empty()) 770 return "trace"; 771 else 772 return m_description.c_str(); 773 } 774 }; 775 776 777 //---------------------------------------------------------------------- 778 // StopInfoException 779 //---------------------------------------------------------------------- 780 781 class StopInfoException : public StopInfo 782 { 783 public: 784 785 StopInfoException (Thread &thread, const char *description) : 786 StopInfo (thread, LLDB_INVALID_UID) 787 { 788 if (description) 789 SetDescription (description); 790 } 791 792 virtual 793 ~StopInfoException () 794 { 795 } 796 797 virtual StopReason 798 GetStopReason () const 799 { 800 return eStopReasonException; 801 } 802 803 virtual const char * 804 GetDescription () 805 { 806 if (m_description.empty()) 807 return "exception"; 808 else 809 return m_description.c_str(); 810 } 811 }; 812 813 814 //---------------------------------------------------------------------- 815 // StopInfoThreadPlan 816 //---------------------------------------------------------------------- 817 818 class StopInfoThreadPlan : public StopInfo 819 { 820 public: 821 822 StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp) : 823 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID), 824 m_plan_sp (plan_sp), 825 m_return_valobj_sp (return_valobj_sp) 826 { 827 } 828 829 virtual ~StopInfoThreadPlan () 830 { 831 } 832 833 virtual StopReason 834 GetStopReason () const 835 { 836 return eStopReasonPlanComplete; 837 } 838 839 virtual const char * 840 GetDescription () 841 { 842 if (m_description.empty()) 843 { 844 StreamString strm; 845 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief); 846 m_description.swap (strm.GetString()); 847 } 848 return m_description.c_str(); 849 } 850 851 ValueObjectSP 852 GetReturnValueObject() 853 { 854 return m_return_valobj_sp; 855 } 856 857 private: 858 ThreadPlanSP m_plan_sp; 859 ValueObjectSP m_return_valobj_sp; 860 }; 861 } // namespace lldb_private 862 863 StopInfoSP 864 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id) 865 { 866 return StopInfoSP (new StopInfoBreakpoint (thread, break_id)); 867 } 868 869 StopInfoSP 870 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop) 871 { 872 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop)); 873 } 874 875 StopInfoSP 876 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id) 877 { 878 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id)); 879 } 880 881 StopInfoSP 882 StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo) 883 { 884 return StopInfoSP (new StopInfoUnixSignal (thread, signo)); 885 } 886 887 StopInfoSP 888 StopInfo::CreateStopReasonToTrace (Thread &thread) 889 { 890 return StopInfoSP (new StopInfoTrace (thread)); 891 } 892 893 StopInfoSP 894 StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp) 895 { 896 return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp)); 897 } 898 899 StopInfoSP 900 StopInfo::CreateStopReasonWithException (Thread &thread, const char *description) 901 { 902 return StopInfoSP (new StopInfoException (thread, description)); 903 } 904 905 ValueObjectSP 906 StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) 907 { 908 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete) 909 { 910 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get()); 911 return plan_stop_info->GetReturnValueObject(); 912 } 913 else 914 return ValueObjectSP(); 915 } 916