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