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/lldb-python.h" 11 12 #include "lldb/Target/StopInfo.h" 13 14 // C Includes 15 // C++ Includes 16 #include <string> 17 18 // Other libraries and framework includes 19 // Project includes 20 #include "lldb/Core/Log.h" 21 #include "lldb/Breakpoint/Breakpoint.h" 22 #include "lldb/Breakpoint/BreakpointLocation.h" 23 #include "lldb/Breakpoint/StoppointCallbackContext.h" 24 #include "lldb/Breakpoint/Watchpoint.h" 25 #include "lldb/Core/Debugger.h" 26 #include "lldb/Core/StreamString.h" 27 #include "lldb/Core/ValueObject.h" 28 #include "lldb/Expression/ClangUserExpression.h" 29 #include "lldb/Target/Target.h" 30 #include "lldb/Target/Thread.h" 31 #include "lldb/Target/ThreadPlan.h" 32 #include "lldb/Target/Process.h" 33 #include "lldb/Target/UnixSignals.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 StopInfo::StopInfo (Thread &thread, uint64_t value) : 39 m_thread_wp (thread.shared_from_this()), 40 m_stop_id (thread.GetProcess()->GetStopID()), 41 m_resume_id (thread.GetProcess()->GetResumeID()), 42 m_value (value), 43 m_override_should_notify (eLazyBoolCalculate), 44 m_override_should_stop (eLazyBoolCalculate), 45 m_extended_info() 46 { 47 } 48 49 bool 50 StopInfo::IsValid () const 51 { 52 ThreadSP thread_sp (m_thread_wp.lock()); 53 if (thread_sp) 54 return thread_sp->GetProcess()->GetStopID() == m_stop_id; 55 return false; 56 } 57 58 void 59 StopInfo::MakeStopInfoValid () 60 { 61 ThreadSP thread_sp (m_thread_wp.lock()); 62 if (thread_sp) 63 { 64 m_stop_id = thread_sp->GetProcess()->GetStopID(); 65 m_resume_id = thread_sp->GetProcess()->GetResumeID(); 66 } 67 } 68 69 bool 70 StopInfo::HasTargetRunSinceMe () 71 { 72 ThreadSP thread_sp (m_thread_wp.lock()); 73 74 if (thread_sp) 75 { 76 lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState(); 77 if (ret_type == eStateRunning) 78 { 79 return true; 80 } 81 else if (ret_type == eStateStopped) 82 { 83 // This is a little tricky. We want to count "run and stopped again before you could 84 // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we don't want to 85 // include any running of the target done for expressions. So we track both resumes, 86 // and resumes caused by expressions, and check if there are any resumes NOT caused 87 // by expressions. 88 89 uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID(); 90 uint32_t last_user_expression_id = thread_sp->GetProcess()->GetLastUserExpressionResumeID (); 91 if (curr_resume_id == m_resume_id) 92 { 93 return false; 94 } 95 else if (curr_resume_id > last_user_expression_id) 96 { 97 return true; 98 } 99 } 100 } 101 return false; 102 } 103 104 //---------------------------------------------------------------------- 105 // StopInfoBreakpoint 106 //---------------------------------------------------------------------- 107 108 namespace lldb_private 109 { 110 class StopInfoBreakpoint : public StopInfo 111 { 112 public: 113 StopInfoBreakpoint (Thread &thread, break_id_t break_id) : 114 StopInfo (thread, break_id), 115 m_description(), 116 m_should_stop (false), 117 m_should_stop_is_valid (false), 118 m_should_perform_action (true), 119 m_address (LLDB_INVALID_ADDRESS), 120 m_break_id(LLDB_INVALID_BREAK_ID), 121 m_was_one_shot (false) 122 { 123 StoreBPInfo(); 124 } 125 126 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) : 127 StopInfo (thread, break_id), 128 m_description(), 129 m_should_stop (should_stop), 130 m_should_stop_is_valid (true), 131 m_should_perform_action (true), 132 m_address (LLDB_INVALID_ADDRESS), 133 m_break_id(LLDB_INVALID_BREAK_ID), 134 m_was_one_shot (false) 135 { 136 StoreBPInfo(); 137 } 138 139 void 140 StoreBPInfo () 141 { 142 ThreadSP thread_sp (m_thread_wp.lock()); 143 if (thread_sp) 144 { 145 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 146 if (bp_site_sp) 147 { 148 if (bp_site_sp->GetNumberOfOwners() == 1) 149 { 150 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0); 151 if (bp_loc_sp) 152 { 153 m_break_id = bp_loc_sp->GetBreakpoint().GetID(); 154 m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot(); 155 } 156 } 157 m_address = bp_site_sp->GetLoadAddress(); 158 } 159 } 160 } 161 162 virtual ~StopInfoBreakpoint () 163 { 164 } 165 166 virtual StopReason 167 GetStopReason () const 168 { 169 return eStopReasonBreakpoint; 170 } 171 172 virtual bool 173 ShouldStopSynchronous (Event *event_ptr) 174 { 175 ThreadSP thread_sp (m_thread_wp.lock()); 176 if (thread_sp) 177 { 178 if (!m_should_stop_is_valid) 179 { 180 // Only check once if we should stop at a breakpoint 181 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 182 if (bp_site_sp) 183 { 184 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0)); 185 StoppointCallbackContext context (event_ptr, exe_ctx, true); 186 bp_site_sp->BumpHitCounts(); 187 m_should_stop = bp_site_sp->ShouldStop (&context); 188 } 189 else 190 { 191 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 192 193 if (log) 194 log->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value); 195 196 m_should_stop = true; 197 } 198 m_should_stop_is_valid = true; 199 } 200 return m_should_stop; 201 } 202 return false; 203 } 204 205 virtual bool 206 DoShouldNotify (Event *event_ptr) 207 { 208 ThreadSP thread_sp (m_thread_wp.lock()); 209 if (thread_sp) 210 { 211 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 212 if (bp_site_sp) 213 { 214 bool all_internal = true; 215 216 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++) 217 { 218 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) 219 { 220 all_internal = false; 221 break; 222 } 223 } 224 return all_internal == false; 225 } 226 } 227 return true; 228 } 229 230 virtual const char * 231 GetDescription () 232 { 233 if (m_description.empty()) 234 { 235 ThreadSP thread_sp (m_thread_wp.lock()); 236 if (thread_sp) 237 { 238 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 239 if (bp_site_sp) 240 { 241 StreamString strm; 242 // If we have just hit an internal breakpoint, and it has a kind description, print that instead of the 243 // full breakpoint printing: 244 if (bp_site_sp->IsInternal()) 245 { 246 size_t num_owners = bp_site_sp->GetNumberOfOwners(); 247 for (size_t idx = 0; idx < num_owners; idx++) 248 { 249 const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind(); 250 if (kind != NULL) 251 { 252 m_description.assign (kind); 253 return kind; 254 } 255 } 256 } 257 258 strm.Printf("breakpoint "); 259 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief); 260 m_description.swap (strm.GetString()); 261 } 262 else 263 { 264 StreamString strm; 265 if (m_break_id != LLDB_INVALID_BREAK_ID) 266 { 267 BreakpointSP break_sp = thread_sp->GetProcess()->GetTarget().GetBreakpointByID(m_break_id); 268 if (break_sp) 269 { 270 if (break_sp->IsInternal()) 271 { 272 const char *kind = break_sp->GetBreakpointKind(); 273 if (kind) 274 strm.Printf ("internal %s breakpoint(%d).", kind, m_break_id); 275 else 276 strm.Printf ("internal breakpoint(%d).", m_break_id); 277 } 278 else 279 { 280 strm.Printf ("breakpoint %d.", m_break_id); 281 } 282 } 283 else 284 { 285 if (m_was_one_shot) 286 strm.Printf ("one-shot breakpoint %d", m_break_id); 287 else 288 strm.Printf ("breakpoint %d which has been deleted.", m_break_id); 289 } 290 } 291 else if (m_address == LLDB_INVALID_ADDRESS) 292 strm.Printf("breakpoint site %" PRIi64 " which has been deleted - unknown address", m_value); 293 else 294 strm.Printf("breakpoint site %" PRIi64 " which has been deleted - was at 0x%" PRIx64, m_value, m_address); 295 296 m_description.swap (strm.GetString()); 297 } 298 } 299 } 300 return m_description.c_str(); 301 } 302 303 protected: 304 bool 305 ShouldStop (Event *event_ptr) 306 { 307 // This just reports the work done by PerformAction or the synchronous stop. It should 308 // only ever get called after they have had a chance to run. 309 assert (m_should_stop_is_valid); 310 return m_should_stop; 311 } 312 313 virtual void 314 PerformAction (Event *event_ptr) 315 { 316 if (!m_should_perform_action) 317 return; 318 m_should_perform_action = false; 319 320 ThreadSP thread_sp (m_thread_wp.lock()); 321 322 if (thread_sp) 323 { 324 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS | LIBLLDB_LOG_STEP); 325 326 if (!thread_sp->IsValid()) 327 { 328 // This shouldn't ever happen, but just in case, don't do more harm. 329 if (log) 330 { 331 log->Printf ("PerformAction got called with an invalid thread."); 332 } 333 m_should_stop = true; 334 m_should_stop_is_valid = true; 335 return; 336 } 337 338 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 339 340 if (bp_site_sp) 341 { 342 size_t num_owners = bp_site_sp->GetNumberOfOwners(); 343 344 if (num_owners == 0) 345 { 346 m_should_stop = true; 347 } 348 else 349 { 350 // We go through each location, and test first its condition. If the condition says to stop, 351 // then we run the callback for that location. If that callback says to stop as well, then 352 // we set m_should_stop to true; we are going to stop. 353 // But we still want to give all the breakpoints whose conditions say we are going to stop a 354 // chance to run their callbacks. 355 // Of course if any callback restarts the target by putting "continue" in the callback, then 356 // we're going to restart, without running the rest of the callbacks. And in this case we will 357 // end up not stopping even if another location said we should stop. But that's better than not 358 // running all the callbacks. 359 360 m_should_stop = false; 361 362 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0)); 363 Process *process = exe_ctx.GetProcessPtr(); 364 if (process->GetModIDRef().IsLastResumeForUserExpression()) 365 { 366 // If we are in the middle of evaluating an expression, don't run asynchronous breakpoint commands or 367 // expressions. That could lead to infinite recursion if the command or condition re-calls the function 368 // with this breakpoint. 369 // TODO: We can keep a list of the breakpoints we've seen while running expressions in the nested 370 // PerformAction calls that can arise when the action runs a function that hits another breakpoint, 371 // and only stop running commands when we see the same breakpoint hit a second time. 372 373 m_should_stop_is_valid = true; 374 if (log) 375 log->Printf ("StopInfoBreakpoint::PerformAction - Hit a breakpoint while running an expression," 376 " not running commands to avoid recursion."); 377 bool ignoring_breakpoints = process->GetIgnoreBreakpointsInExpressions(); 378 if (ignoring_breakpoints) 379 { 380 m_should_stop = false; 381 // Internal breakpoints will always stop. 382 for (size_t j = 0; j < num_owners; j++) 383 { 384 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j); 385 if (bp_loc_sp->GetBreakpoint().IsInternal()) 386 { 387 m_should_stop = true; 388 break; 389 } 390 } 391 } 392 else 393 { 394 m_should_stop = true; 395 } 396 if (log) 397 log->Printf ("StopInfoBreakpoint::PerformAction - in expression, continuing: %s.", 398 m_should_stop ? "true" : "false"); 399 process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: hit breakpoint while " 400 "running function, skipping commands and conditions to prevent recursion."); 401 return; 402 } 403 404 StoppointCallbackContext context (event_ptr, exe_ctx, false); 405 406 // Let's copy the breakpoint locations out of the site and store them in a local list. That way if 407 // one of the breakpoint actions changes the site, then we won't be operating on a bad list. 408 // For safety's sake let's also grab an extra reference to the breakpoint owners of the locations we're 409 // going to examine, since the locations are going to have to get back to their breakpoints, and the 410 // locations don't keep their owners alive. I'm just sticking the BreakpointSP's in a vector since 411 // I'm only really using it to locally increment their retain counts. 412 413 BreakpointLocationCollection site_locations; 414 std::vector<lldb::BreakpointSP> location_owners; 415 416 for (size_t j = 0; j < num_owners; j++) 417 { 418 BreakpointLocationSP loc(bp_site_sp->GetOwnerAtIndex(j)); 419 site_locations.Add(loc); 420 location_owners.push_back(loc->GetBreakpoint().shared_from_this()); 421 422 } 423 424 for (size_t j = 0; j < num_owners; j++) 425 { 426 lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j); 427 428 // If another action disabled this breakpoint or its location, then don't run the actions. 429 if (!bp_loc_sp->IsEnabled() || !bp_loc_sp->GetBreakpoint().IsEnabled()) 430 continue; 431 432 // The breakpoint site may have many locations associated with it, not all of them valid for 433 // this thread. Skip the ones that aren't: 434 if (!bp_loc_sp->ValidForThisThread(thread_sp.get())) 435 { 436 if (log) 437 { 438 StreamString s; 439 bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief); 440 log->Printf ("Breakpoint %s hit on thread 0x%llx but it was not for this thread, continuing.", 441 s.GetData(), 442 static_cast<unsigned long long>(thread_sp->GetID())); 443 } 444 continue; 445 } 446 // First run the condition for the breakpoint. If that says we should stop, then we'll run 447 // the callback for the breakpoint. If the callback says we shouldn't stop that will win. 448 449 if (bp_loc_sp->GetConditionText() != NULL) 450 { 451 Error condition_error; 452 bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error); 453 454 if (!condition_error.Success()) 455 { 456 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 457 StreamSP error_sp = debugger.GetAsyncErrorStream (); 458 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint "); 459 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 460 error_sp->Printf (": \"%s\"", 461 bp_loc_sp->GetConditionText()); 462 error_sp->EOL(); 463 const char *err_str = condition_error.AsCString("<Unknown Error>"); 464 if (log) 465 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 466 467 error_sp->PutCString (err_str); 468 error_sp->EOL(); 469 error_sp->Flush(); 470 } 471 else 472 { 473 if (log) 474 { 475 StreamString s; 476 bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief); 477 log->Printf ("Condition evaluated for breakpoint %s on thread 0x%llx conditon_says_stop: %i.", 478 s.GetData(), 479 static_cast<unsigned long long>(thread_sp->GetID()), 480 condition_says_stop); 481 } 482 if (!condition_says_stop) 483 { 484 // We don't want to increment the hit count of breakpoints if the condition fails. 485 // We've already bumped it by the time we get here, so undo the bump: 486 bp_loc_sp->UndoBumpHitCount(); 487 continue; 488 } 489 } 490 } 491 492 bool callback_says_stop; 493 494 // FIXME: For now the callbacks have to run in async mode - the first time we restart we need 495 // to get out of there. So set it here. 496 // When we figure out how to nest breakpoint hits then this will change. 497 498 Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger(); 499 bool old_async = debugger.GetAsyncExecution(); 500 debugger.SetAsyncExecution (true); 501 502 callback_says_stop = bp_loc_sp->InvokeCallback (&context); 503 504 debugger.SetAsyncExecution (old_async); 505 506 if (callback_says_stop) 507 m_should_stop = true; 508 509 // If we are going to stop for this breakpoint, then remove the breakpoint. 510 if (callback_says_stop && bp_loc_sp && bp_loc_sp->GetBreakpoint().IsOneShot()) 511 { 512 thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID (bp_loc_sp->GetBreakpoint().GetID()); 513 } 514 515 // Also make sure that the callback hasn't continued the target. 516 // If it did, when we'll set m_should_start to false and get out of here. 517 if (HasTargetRunSinceMe ()) 518 { 519 m_should_stop = false; 520 break; 521 } 522 } 523 } 524 // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again. 525 m_should_stop_is_valid = true; 526 527 } 528 else 529 { 530 m_should_stop = true; 531 m_should_stop_is_valid = true; 532 Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 533 534 if (log_process) 535 log_process->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value); 536 } 537 if (log) 538 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 539 } 540 } 541 542 private: 543 std::string m_description; 544 bool m_should_stop; 545 bool m_should_stop_is_valid; 546 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions 547 // etc. behind the users backs, we need to make sure we only REALLY perform the action once. 548 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo, 549 // in case somebody deletes it between the time the StopInfo is made and the 550 // description is asked for. 551 lldb::break_id_t m_break_id; 552 bool m_was_one_shot; 553 }; 554 555 556 //---------------------------------------------------------------------- 557 // StopInfoWatchpoint 558 //---------------------------------------------------------------------- 559 560 class StopInfoWatchpoint : public StopInfo 561 { 562 public: 563 // Make sure watchpoint is properly disabled and subsequently enabled while performing watchpoint actions. 564 class WatchpointSentry { 565 public: 566 WatchpointSentry(Process *p, Watchpoint *w): 567 process(p), 568 watchpoint(w) 569 { 570 if (process && watchpoint) 571 { 572 const bool notify = false; 573 watchpoint->TurnOnEphemeralMode(); 574 process->DisableWatchpoint(watchpoint, notify); 575 } 576 } 577 ~WatchpointSentry() 578 { 579 if (process && watchpoint) 580 { 581 if (!watchpoint->IsDisabledDuringEphemeralMode()) 582 { 583 const bool notify = false; 584 process->EnableWatchpoint(watchpoint, notify); 585 } 586 watchpoint->TurnOffEphemeralMode(); 587 } 588 } 589 private: 590 Process *process; 591 Watchpoint *watchpoint; 592 }; 593 594 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) : 595 StopInfo(thread, watch_id), 596 m_description(), 597 m_should_stop(false), 598 m_should_stop_is_valid(false) 599 { 600 } 601 602 virtual ~StopInfoWatchpoint () 603 { 604 } 605 606 virtual StopReason 607 GetStopReason () const 608 { 609 return eStopReasonWatchpoint; 610 } 611 612 virtual const char * 613 GetDescription () 614 { 615 if (m_description.empty()) 616 { 617 StreamString strm; 618 strm.Printf("watchpoint %" PRIi64, m_value); 619 m_description.swap (strm.GetString()); 620 } 621 return m_description.c_str(); 622 } 623 624 protected: 625 virtual bool 626 ShouldStopSynchronous (Event *event_ptr) 627 { 628 // ShouldStop() method is idempotent and should not affect hit count. 629 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent() 630 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()-> 631 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()-> 632 // StopInfoWatchpoint::ShouldStop() and 633 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()-> 634 // StopInfoWatchpoint::PerformAction(). 635 if (m_should_stop_is_valid) 636 return m_should_stop; 637 638 ThreadSP thread_sp (m_thread_wp.lock()); 639 if (thread_sp) 640 { 641 WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue())); 642 if (wp_sp) 643 { 644 // Check if we should stop at a watchpoint. 645 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0)); 646 StoppointCallbackContext context (event_ptr, exe_ctx, true); 647 m_should_stop = wp_sp->ShouldStop (&context); 648 } 649 else 650 { 651 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 652 653 if (log) 654 log->Printf ("Process::%s could not find watchpoint location id: %" PRId64 "...", 655 __FUNCTION__, GetValue()); 656 657 m_should_stop = true; 658 } 659 } 660 m_should_stop_is_valid = true; 661 return m_should_stop; 662 } 663 664 bool 665 ShouldStop (Event *event_ptr) 666 { 667 // This just reports the work done by PerformAction or the synchronous stop. It should 668 // only ever get called after they have had a chance to run. 669 assert (m_should_stop_is_valid); 670 return m_should_stop; 671 } 672 673 virtual void 674 PerformAction (Event *event_ptr) 675 { 676 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS); 677 // We're going to calculate if we should stop or not in some way during the course of 678 // this code. Also by default we're going to stop, so set that here. 679 m_should_stop = true; 680 681 ThreadSP thread_sp (m_thread_wp.lock()); 682 if (thread_sp) 683 { 684 685 WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue())); 686 if (wp_sp) 687 { 688 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0)); 689 Process* process = exe_ctx.GetProcessPtr(); 690 691 // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions, 692 // and it is then enabled after we are finished. 693 WatchpointSentry sentry(process, wp_sp.get()); 694 695 { 696 // check if this process is running on an architecture where watchpoints trigger 697 // before the associated instruction runs. if so, disable the WP, single-step and then 698 // re-enable the watchpoint 699 if (process) 700 { 701 uint32_t num; 702 bool wp_triggers_after; 703 if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success()) 704 { 705 if (!wp_triggers_after) 706 { 707 StopInfoSP stored_stop_info_sp = thread_sp->GetStopInfo(); 708 assert (stored_stop_info_sp.get() == this); 709 710 ThreadPlanSP new_plan_sp(thread_sp->QueueThreadPlanForStepSingleInstruction(false, // step-over 711 false, // abort_other_plans 712 true)); // stop_other_threads 713 new_plan_sp->SetIsMasterPlan (true); 714 new_plan_sp->SetOkayToDiscard (false); 715 new_plan_sp->SetPrivate (true); 716 process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 717 process->ResumeSynchronous(NULL); 718 process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 719 thread_sp->SetStopInfo(stored_stop_info_sp); 720 } 721 } 722 } 723 } 724 725 if (m_should_stop && wp_sp->GetConditionText() != NULL) 726 { 727 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 728 // constructor errors up to the debugger's Async I/O. 729 ExpressionResults result_code; 730 EvaluateExpressionOptions expr_options; 731 expr_options.SetUnwindOnError(true); 732 expr_options.SetIgnoreBreakpoints(true); 733 ValueObjectSP result_value_sp; 734 Error error; 735 result_code = ClangUserExpression::Evaluate (exe_ctx, 736 expr_options, 737 wp_sp->GetConditionText(), 738 NULL, 739 result_value_sp, 740 error); 741 if (result_code == eExpressionCompleted) 742 { 743 if (result_value_sp) 744 { 745 Scalar scalar_value; 746 if (result_value_sp->ResolveValue (scalar_value)) 747 { 748 if (scalar_value.ULongLong(1) == 0) 749 { 750 // We have been vetoed. This takes precedence over querying 751 // the watchpoint whether it should stop (aka ignore count and 752 // friends). See also StopInfoWatchpoint::ShouldStop() as well 753 // as Process::ProcessEventData::DoOnRemoval(). 754 m_should_stop = false; 755 } 756 else 757 m_should_stop = true; 758 if (log) 759 log->Printf("Condition successfully evaluated, result is %s.\n", 760 m_should_stop ? "true" : "false"); 761 } 762 else 763 { 764 m_should_stop = true; 765 if (log) 766 log->Printf("Failed to get an integer result from the expression."); 767 } 768 } 769 } 770 else 771 { 772 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 773 StreamSP error_sp = debugger.GetAsyncErrorStream (); 774 error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint "); 775 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 776 error_sp->Printf (": \"%s\"", 777 wp_sp->GetConditionText()); 778 error_sp->EOL(); 779 const char *err_str = error.AsCString("<Unknown Error>"); 780 if (log) 781 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 782 783 error_sp->PutCString (err_str); 784 error_sp->EOL(); 785 error_sp->Flush(); 786 // If the condition fails to be parsed or run, we should stop. 787 m_should_stop = true; 788 } 789 } 790 791 // If the condition says to stop, we run the callback to further decide whether to stop. 792 if (m_should_stop) 793 { 794 StoppointCallbackContext context (event_ptr, exe_ctx, false); 795 bool stop_requested = wp_sp->InvokeCallback (&context); 796 // Also make sure that the callback hasn't continued the target. 797 // If it did, when we'll set m_should_stop to false and get out of here. 798 if (HasTargetRunSinceMe ()) 799 m_should_stop = false; 800 801 if (m_should_stop && !stop_requested) 802 { 803 // We have been vetoed by the callback mechanism. 804 m_should_stop = false; 805 } 806 } 807 // Finally, if we are going to stop, print out the new & old values: 808 if (m_should_stop) 809 { 810 wp_sp->CaptureWatchedValue(exe_ctx); 811 812 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 813 StreamSP output_sp = debugger.GetAsyncOutputStream (); 814 wp_sp->DumpSnapshots(output_sp.get()); 815 output_sp->EOL(); 816 output_sp->Flush(); 817 } 818 819 } 820 else 821 { 822 Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 823 824 if (log_process) 825 log_process->Printf ("Process::%s could not find watchpoint id: %" PRId64 "...", __FUNCTION__, m_value); 826 } 827 if (log) 828 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 829 830 m_should_stop_is_valid = true; 831 } 832 } 833 834 private: 835 std::string m_description; 836 bool m_should_stop; 837 bool m_should_stop_is_valid; 838 }; 839 840 841 842 //---------------------------------------------------------------------- 843 // StopInfoUnixSignal 844 //---------------------------------------------------------------------- 845 846 class StopInfoUnixSignal : public StopInfo 847 { 848 public: 849 850 StopInfoUnixSignal (Thread &thread, int signo) : 851 StopInfo (thread, signo) 852 { 853 } 854 855 virtual ~StopInfoUnixSignal () 856 { 857 } 858 859 860 virtual StopReason 861 GetStopReason () const 862 { 863 return eStopReasonSignal; 864 } 865 866 virtual bool 867 ShouldStopSynchronous (Event *event_ptr) 868 { 869 ThreadSP thread_sp (m_thread_wp.lock()); 870 if (thread_sp) 871 return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value); 872 return false; 873 } 874 875 virtual bool 876 ShouldStop (Event *event_ptr) 877 { 878 ThreadSP thread_sp (m_thread_wp.lock()); 879 if (thread_sp) 880 return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value); 881 return false; 882 } 883 884 885 // If should stop returns false, check if we should notify of this event 886 virtual bool 887 DoShouldNotify (Event *event_ptr) 888 { 889 ThreadSP thread_sp (m_thread_wp.lock()); 890 if (thread_sp) 891 { 892 bool should_notify = thread_sp->GetProcess()->GetUnixSignals().GetShouldNotify (m_value); 893 if (should_notify) 894 { 895 StreamString strm; 896 strm.Printf ("thread %d received signal: %s", 897 thread_sp->GetIndexID(), 898 thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value)); 899 Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData()); 900 } 901 return should_notify; 902 } 903 return true; 904 } 905 906 907 virtual void 908 WillResume (lldb::StateType resume_state) 909 { 910 ThreadSP thread_sp (m_thread_wp.lock()); 911 if (thread_sp) 912 { 913 if (thread_sp->GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false) 914 thread_sp->SetResumeSignal(m_value); 915 } 916 } 917 918 virtual const char * 919 GetDescription () 920 { 921 if (m_description.empty()) 922 { 923 ThreadSP thread_sp (m_thread_wp.lock()); 924 if (thread_sp) 925 { 926 StreamString strm; 927 const char *signal_name = thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value); 928 if (signal_name) 929 strm.Printf("signal %s", signal_name); 930 else 931 strm.Printf("signal %" PRIi64, m_value); 932 m_description.swap (strm.GetString()); 933 } 934 } 935 return m_description.c_str(); 936 } 937 }; 938 939 //---------------------------------------------------------------------- 940 // StopInfoTrace 941 //---------------------------------------------------------------------- 942 943 class StopInfoTrace : public StopInfo 944 { 945 public: 946 947 StopInfoTrace (Thread &thread) : 948 StopInfo (thread, LLDB_INVALID_UID) 949 { 950 } 951 952 virtual ~StopInfoTrace () 953 { 954 } 955 956 virtual StopReason 957 GetStopReason () const 958 { 959 return eStopReasonTrace; 960 } 961 962 virtual const char * 963 GetDescription () 964 { 965 if (m_description.empty()) 966 return "trace"; 967 else 968 return m_description.c_str(); 969 } 970 }; 971 972 973 //---------------------------------------------------------------------- 974 // StopInfoException 975 //---------------------------------------------------------------------- 976 977 class StopInfoException : public StopInfo 978 { 979 public: 980 981 StopInfoException (Thread &thread, const char *description) : 982 StopInfo (thread, LLDB_INVALID_UID) 983 { 984 if (description) 985 SetDescription (description); 986 } 987 988 virtual 989 ~StopInfoException () 990 { 991 } 992 993 virtual StopReason 994 GetStopReason () const 995 { 996 return eStopReasonException; 997 } 998 999 virtual const char * 1000 GetDescription () 1001 { 1002 if (m_description.empty()) 1003 return "exception"; 1004 else 1005 return m_description.c_str(); 1006 } 1007 }; 1008 1009 1010 //---------------------------------------------------------------------- 1011 // StopInfoThreadPlan 1012 //---------------------------------------------------------------------- 1013 1014 class StopInfoThreadPlan : public StopInfo 1015 { 1016 public: 1017 1018 StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp, ClangExpressionVariableSP &expression_variable_sp) : 1019 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID), 1020 m_plan_sp (plan_sp), 1021 m_return_valobj_sp (return_valobj_sp), 1022 m_expression_variable_sp (expression_variable_sp) 1023 { 1024 } 1025 1026 virtual ~StopInfoThreadPlan () 1027 { 1028 } 1029 1030 virtual StopReason 1031 GetStopReason () const 1032 { 1033 return eStopReasonPlanComplete; 1034 } 1035 1036 virtual const char * 1037 GetDescription () 1038 { 1039 if (m_description.empty()) 1040 { 1041 StreamString strm; 1042 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief); 1043 m_description.swap (strm.GetString()); 1044 } 1045 return m_description.c_str(); 1046 } 1047 1048 ValueObjectSP 1049 GetReturnValueObject() 1050 { 1051 return m_return_valobj_sp; 1052 } 1053 1054 ClangExpressionVariableSP 1055 GetExpressionVariable() 1056 { 1057 return m_expression_variable_sp; 1058 } 1059 1060 protected: 1061 virtual bool 1062 ShouldStop (Event *event_ptr) 1063 { 1064 if (m_plan_sp) 1065 return m_plan_sp->ShouldStop(event_ptr); 1066 else 1067 return StopInfo::ShouldStop(event_ptr); 1068 } 1069 1070 private: 1071 ThreadPlanSP m_plan_sp; 1072 ValueObjectSP m_return_valobj_sp; 1073 ClangExpressionVariableSP m_expression_variable_sp; 1074 }; 1075 1076 class StopInfoExec : public StopInfo 1077 { 1078 public: 1079 1080 StopInfoExec (Thread &thread) : 1081 StopInfo (thread, LLDB_INVALID_UID), 1082 m_performed_action (false) 1083 { 1084 } 1085 1086 virtual 1087 ~StopInfoExec () 1088 { 1089 } 1090 1091 virtual StopReason 1092 GetStopReason () const 1093 { 1094 return eStopReasonExec; 1095 } 1096 1097 virtual const char * 1098 GetDescription () 1099 { 1100 return "exec"; 1101 } 1102 protected: 1103 1104 virtual void 1105 PerformAction (Event *event_ptr) 1106 { 1107 // Only perform the action once 1108 if (m_performed_action) 1109 return; 1110 m_performed_action = true; 1111 ThreadSP thread_sp (m_thread_wp.lock()); 1112 if (thread_sp) 1113 thread_sp->GetProcess()->DidExec(); 1114 } 1115 1116 bool m_performed_action; 1117 }; 1118 1119 } // namespace lldb_private 1120 1121 StopInfoSP 1122 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id) 1123 { 1124 return StopInfoSP (new StopInfoBreakpoint (thread, break_id)); 1125 } 1126 1127 StopInfoSP 1128 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop) 1129 { 1130 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop)); 1131 } 1132 1133 StopInfoSP 1134 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id) 1135 { 1136 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id)); 1137 } 1138 1139 StopInfoSP 1140 StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo) 1141 { 1142 return StopInfoSP (new StopInfoUnixSignal (thread, signo)); 1143 } 1144 1145 StopInfoSP 1146 StopInfo::CreateStopReasonToTrace (Thread &thread) 1147 { 1148 return StopInfoSP (new StopInfoTrace (thread)); 1149 } 1150 1151 StopInfoSP 1152 StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, 1153 ValueObjectSP return_valobj_sp, 1154 ClangExpressionVariableSP expression_variable_sp) 1155 { 1156 return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp, expression_variable_sp)); 1157 } 1158 1159 StopInfoSP 1160 StopInfo::CreateStopReasonWithException (Thread &thread, const char *description) 1161 { 1162 return StopInfoSP (new StopInfoException (thread, description)); 1163 } 1164 1165 StopInfoSP 1166 StopInfo::CreateStopReasonWithExec (Thread &thread) 1167 { 1168 return StopInfoSP (new StopInfoExec (thread)); 1169 } 1170 1171 ValueObjectSP 1172 StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) 1173 { 1174 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete) 1175 { 1176 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get()); 1177 return plan_stop_info->GetReturnValueObject(); 1178 } 1179 else 1180 return ValueObjectSP(); 1181 } 1182 1183 ClangExpressionVariableSP 1184 StopInfo::GetExpressionVariable(StopInfoSP &stop_info_sp) 1185 { 1186 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete) 1187 { 1188 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get()); 1189 return plan_stop_info->GetExpressionVariable(); 1190 } 1191 else 1192 return ClangExpressionVariableSP(); 1193 } 1194