StopInfo.cpp revision a539e5bd8dc9fcdf1e3dbffff86d9f6fd9750837
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 32using namespace lldb; 33using namespace lldb_private; 34 35StopInfo::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 43bool 44StopInfo::IsValid () const 45{ 46 return m_thread.GetProcess()->GetStopID() == m_stop_id; 47} 48 49void 50StopInfo::MakeStopInfoValid () 51{ 52 m_stop_id = m_thread.GetProcess()->GetStopID(); 53 m_resume_id = m_thread.GetProcess()->GetResumeID(); 54} 55 56bool 57StopInfo::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 90namespace lldb_private 91{ 92class StopInfoBreakpoint : public StopInfo 93{ 94public: 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 375private: 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 391class StopInfoWatchpoint : public StopInfo 392{ 393public: 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 // Make sure watchpoint is properly disabled and subsequently enabled while performing watchpoint actions. 450 class WatchpointSentry { 451 public: 452 WatchpointSentry(Process *p, Watchpoint *w): 453 process(p), 454 watchpoint(w) 455 { 456 if (process && watchpoint) 457 { 458 watchpoint->TurnOnEphemeralMode(); 459 process->DisableWatchpoint(watchpoint); 460 } 461 } 462 ~WatchpointSentry() 463 { 464 if (process && watchpoint) 465 { 466 if (!watchpoint->IsDisabledDuringEphemeralMode()) 467 process->EnableWatchpoint(watchpoint); 468 watchpoint->TurnOffEphemeralMode(); 469 } 470 } 471 private: 472 Process *process; 473 Watchpoint *watchpoint; 474 }; 475 476 // Perform any action that is associated with this stop. This is done as the 477 // Event is removed from the event queue. 478 virtual void 479 PerformAction (Event *event_ptr) 480 { 481 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS); 482 // We're going to calculate if we should stop or not in some way during the course of 483 // this code. Also by default we're going to stop, so set that here. 484 m_should_stop = true; 485 486 WatchpointSP wp_sp = 487 m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue()); 488 if (wp_sp) 489 { 490 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 491 Process* process = exe_ctx.GetProcessPtr(); 492 493 // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions, 494 // and it is then enabled after we are finished. 495 WatchpointSentry sentry(process, wp_sp.get()); 496 497 { 498 // check if this process is running on an architecture where watchpoints trigger 499 // before the associated instruction runs. if so, disable the WP, single-step and then 500 // re-enable the watchpoint 501 if (process) 502 { 503 uint32_t num; bool wp_triggers_after; 504 if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success()) 505 { 506 if (!wp_triggers_after) 507 { 508 ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over 509 false, // abort_other_plans 510 true); // stop_other_threads 511 new_plan->SetIsMasterPlan (true); 512 new_plan->SetOkayToDiscard (false); 513 process->GetThreadList().SetSelectedThreadByID (m_thread.GetID()); 514 process->Resume (); 515 process->WaitForProcessToStop (NULL); 516 process->GetThreadList().SetSelectedThreadByID (m_thread.GetID()); 517 MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above 518 } 519 } 520 } 521 } 522 523 // Record the snapshot of our watchpoint. 524 VariableSP var_sp; 525 ValueObjectSP valobj_sp; 526 StackFrame *frame = exe_ctx.GetFramePtr(); 527 if (frame) 528 { 529 bool snapshot_taken = true; 530 if (!wp_sp->IsWatchVariable()) 531 { 532 // We are not watching a variable, just read from the process memory for the watched location. 533 assert (process); 534 Error error; 535 uint64_t val = process->ReadUnsignedIntegerFromMemory(wp_sp->GetLoadAddress(), 536 wp_sp->GetByteSize(), 537 0, 538 error); 539 if (log) 540 { 541 if (error.Success()) 542 log->Printf("Watchpoint snapshot val taken: 0x%llx\n", val); 543 else 544 log->Printf("Watchpoint snapshot val taking failed.\n"); 545 } 546 wp_sp->SetNewSnapshotVal(val); 547 } 548 else if (!wp_sp->GetWatchSpec().empty()) 549 { 550 // Use our frame to evaluate the variable expression. 551 Error error; 552 uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember | 553 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess; 554 valobj_sp = frame->GetValueForVariableExpressionPath (wp_sp->GetWatchSpec().c_str(), 555 eNoDynamicValues, 556 expr_path_options, 557 var_sp, 558 error); 559 if (valobj_sp) 560 { 561 // We're in business. 562 StreamString ss; 563 ValueObject::DumpValueObject(ss, valobj_sp.get()); 564 wp_sp->SetNewSnapshot(ss.GetString()); 565 } 566 else 567 { 568 // The variable expression has become out of scope? 569 // Let us forget about this stop info. 570 if (log) 571 log->Printf("Snapshot attempt failed. Variable expression has become out of scope?"); 572 snapshot_taken = false; 573 m_should_stop = false; 574 wp_sp->IncrementFalseAlarmsAndReviseHitCount(); 575 } 576 577 if (log && snapshot_taken) 578 log->Printf("Watchpoint snapshot taken: '%s'\n", wp_sp->GetNewSnapshot().c_str()); 579 } 580 581 // Now dump the snapshots we have taken. 582 if (snapshot_taken) 583 { 584 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 585 StreamSP output_sp = debugger.GetAsyncOutputStream (); 586 wp_sp->DumpSnapshots(output_sp.get()); 587 output_sp->EOL(); 588 output_sp->Flush(); 589 } 590 } 591 592 if (m_should_stop && wp_sp->GetConditionText() != NULL) 593 { 594 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 595 // constructor errors up to the debugger's Async I/O. 596 ExecutionResults result_code; 597 ValueObjectSP result_value_sp; 598 const bool discard_on_error = true; 599 Error error; 600 result_code = ClangUserExpression::EvaluateWithError (exe_ctx, 601 eExecutionPolicyOnlyWhenNeeded, 602 lldb::eLanguageTypeUnknown, 603 ClangUserExpression::eResultTypeAny, 604 discard_on_error, 605 wp_sp->GetConditionText(), 606 NULL, 607 result_value_sp, 608 error, 609 500000); 610 if (result_code == eExecutionCompleted) 611 { 612 if (result_value_sp) 613 { 614 Scalar scalar_value; 615 if (result_value_sp->ResolveValue (scalar_value)) 616 { 617 if (scalar_value.ULongLong(1) == 0) 618 { 619 // We have been vetoed. This takes precedence over querying 620 // the watchpoint whether it should stop (aka ignore count and 621 // friends). See also StopInfoWatchpoint::ShouldStop() as well 622 // as Process::ProcessEventData::DoOnRemoval(). 623 m_should_stop = false; 624 } 625 else 626 m_should_stop = true; 627 if (log) 628 log->Printf("Condition successfully evaluated, result is %s.\n", 629 m_should_stop ? "true" : "false"); 630 } 631 else 632 { 633 m_should_stop = true; 634 if (log) 635 log->Printf("Failed to get an integer result from the expression."); 636 } 637 } 638 } 639 else 640 { 641 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 642 StreamSP error_sp = debugger.GetAsyncErrorStream (); 643 error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint "); 644 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 645 error_sp->Printf (": \"%s\"", 646 wp_sp->GetConditionText()); 647 error_sp->EOL(); 648 const char *err_str = error.AsCString("<Unknown Error>"); 649 if (log) 650 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 651 652 error_sp->PutCString (err_str); 653 error_sp->EOL(); 654 error_sp->Flush(); 655 // If the condition fails to be parsed or run, we should stop. 656 m_should_stop = true; 657 } 658 } 659 660 // If the condition says to stop, we run the callback to further decide whether to stop. 661 if (m_should_stop) 662 { 663 StoppointCallbackContext context (event_ptr, exe_ctx, false); 664 bool stop_requested = wp_sp->InvokeCallback (&context); 665 // Also make sure that the callback hasn't continued the target. 666 // If it did, when we'll set m_should_stop to false and get out of here. 667 if (HasTargetRunSinceMe ()) 668 m_should_stop = false; 669 670 if (m_should_stop && !stop_requested) 671 { 672 // We have been vetoed by the callback mechanism. 673 m_should_stop = false; 674 } 675 } 676 } 677 else 678 { 679 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 680 681 if (log) 682 log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value); 683 } 684 if (log) 685 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 686 } 687 688 virtual const char * 689 GetDescription () 690 { 691 if (m_description.empty()) 692 { 693 StreamString strm; 694 strm.Printf("watchpoint %lli", m_value); 695 m_description.swap (strm.GetString()); 696 } 697 return m_description.c_str(); 698 } 699 700private: 701 std::string m_description; 702 bool m_should_stop; 703 bool m_should_stop_is_valid; 704}; 705 706 707 708//---------------------------------------------------------------------- 709// StopInfoUnixSignal 710//---------------------------------------------------------------------- 711 712class StopInfoUnixSignal : public StopInfo 713{ 714public: 715 716 StopInfoUnixSignal (Thread &thread, int signo) : 717 StopInfo (thread, signo) 718 { 719 } 720 721 virtual ~StopInfoUnixSignal () 722 { 723 } 724 725 726 virtual StopReason 727 GetStopReason () const 728 { 729 return eStopReasonSignal; 730 } 731 732 virtual bool 733 ShouldStop (Event *event_ptr) 734 { 735 return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value); 736 } 737 738 739 // If should stop returns false, check if we should notify of this event 740 virtual bool 741 ShouldNotify (Event *event_ptr) 742 { 743 return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value); 744 } 745 746 747 virtual void 748 WillResume (lldb::StateType resume_state) 749 { 750 if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false) 751 m_thread.SetResumeSignal(m_value); 752 } 753 754 virtual const char * 755 GetDescription () 756 { 757 if (m_description.empty()) 758 { 759 StreamString strm; 760 const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value); 761 if (signal_name) 762 strm.Printf("signal %s", signal_name); 763 else 764 strm.Printf("signal %lli", m_value); 765 m_description.swap (strm.GetString()); 766 } 767 return m_description.c_str(); 768 } 769}; 770 771//---------------------------------------------------------------------- 772// StopInfoTrace 773//---------------------------------------------------------------------- 774 775class StopInfoTrace : public StopInfo 776{ 777public: 778 779 StopInfoTrace (Thread &thread) : 780 StopInfo (thread, LLDB_INVALID_UID) 781 { 782 } 783 784 virtual ~StopInfoTrace () 785 { 786 } 787 788 virtual StopReason 789 GetStopReason () const 790 { 791 return eStopReasonTrace; 792 } 793 794 virtual const char * 795 GetDescription () 796 { 797 if (m_description.empty()) 798 return "trace"; 799 else 800 return m_description.c_str(); 801 } 802}; 803 804 805//---------------------------------------------------------------------- 806// StopInfoException 807//---------------------------------------------------------------------- 808 809class StopInfoException : public StopInfo 810{ 811public: 812 813 StopInfoException (Thread &thread, const char *description) : 814 StopInfo (thread, LLDB_INVALID_UID) 815 { 816 if (description) 817 SetDescription (description); 818 } 819 820 virtual 821 ~StopInfoException () 822 { 823 } 824 825 virtual StopReason 826 GetStopReason () const 827 { 828 return eStopReasonException; 829 } 830 831 virtual const char * 832 GetDescription () 833 { 834 if (m_description.empty()) 835 return "exception"; 836 else 837 return m_description.c_str(); 838 } 839}; 840 841 842//---------------------------------------------------------------------- 843// StopInfoThreadPlan 844//---------------------------------------------------------------------- 845 846class StopInfoThreadPlan : public StopInfo 847{ 848public: 849 850 StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp) : 851 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID), 852 m_plan_sp (plan_sp), 853 m_return_valobj_sp (return_valobj_sp) 854 { 855 } 856 857 virtual ~StopInfoThreadPlan () 858 { 859 } 860 861 virtual StopReason 862 GetStopReason () const 863 { 864 return eStopReasonPlanComplete; 865 } 866 867 virtual const char * 868 GetDescription () 869 { 870 if (m_description.empty()) 871 { 872 StreamString strm; 873 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief); 874 m_description.swap (strm.GetString()); 875 } 876 return m_description.c_str(); 877 } 878 879 ValueObjectSP 880 GetReturnValueObject() 881 { 882 return m_return_valobj_sp; 883 } 884 885private: 886 ThreadPlanSP m_plan_sp; 887 ValueObjectSP m_return_valobj_sp; 888}; 889} // namespace lldb_private 890 891StopInfoSP 892StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id) 893{ 894 return StopInfoSP (new StopInfoBreakpoint (thread, break_id)); 895} 896 897StopInfoSP 898StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop) 899{ 900 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop)); 901} 902 903StopInfoSP 904StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id) 905{ 906 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id)); 907} 908 909StopInfoSP 910StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo) 911{ 912 return StopInfoSP (new StopInfoUnixSignal (thread, signo)); 913} 914 915StopInfoSP 916StopInfo::CreateStopReasonToTrace (Thread &thread) 917{ 918 return StopInfoSP (new StopInfoTrace (thread)); 919} 920 921StopInfoSP 922StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp) 923{ 924 return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp)); 925} 926 927StopInfoSP 928StopInfo::CreateStopReasonWithException (Thread &thread, const char *description) 929{ 930 return StopInfoSP (new StopInfoException (thread, description)); 931} 932 933ValueObjectSP 934StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) 935{ 936 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete) 937 { 938 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get()); 939 return plan_stop_info->GetReturnValueObject(); 940 } 941 else 942 return ValueObjectSP(); 943} 944