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_value (value) 39 { 40 } 41 42 bool 43 StopInfo::IsValid () const 44 { 45 return m_thread.GetProcess().GetStopID() == m_stop_id; 46 } 47 48 void 49 StopInfo::MakeStopInfoValid () 50 { 51 m_stop_id = m_thread.GetProcess().GetStopID(); 52 } 53 54 lldb::StateType 55 StopInfo::GetPrivateState () 56 { 57 return m_thread.GetProcess().GetPrivateState(); 58 } 59 60 //---------------------------------------------------------------------- 61 // StopInfoBreakpoint 62 //---------------------------------------------------------------------- 63 64 namespace lldb_private 65 { 66 class StopInfoBreakpoint : public StopInfo 67 { 68 public: 69 70 StopInfoBreakpoint (Thread &thread, break_id_t break_id) : 71 StopInfo (thread, break_id), 72 m_description(), 73 m_should_stop (false), 74 m_should_stop_is_valid (false), 75 m_should_perform_action (true), 76 m_address (LLDB_INVALID_ADDRESS) 77 { 78 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); 79 if (bp_site_sp) 80 { 81 m_address = bp_site_sp->GetLoadAddress(); 82 } 83 } 84 85 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) : 86 StopInfo (thread, break_id), 87 m_description(), 88 m_should_stop (should_stop), 89 m_should_stop_is_valid (true), 90 m_should_perform_action (true), 91 m_address (LLDB_INVALID_ADDRESS) 92 { 93 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); 94 if (bp_site_sp) 95 { 96 m_address = bp_site_sp->GetLoadAddress(); 97 } 98 } 99 100 virtual ~StopInfoBreakpoint () 101 { 102 } 103 104 virtual StopReason 105 GetStopReason () const 106 { 107 return eStopReasonBreakpoint; 108 } 109 110 virtual bool 111 ShouldStop (Event *event_ptr) 112 { 113 if (!m_should_stop_is_valid) 114 { 115 // Only check once if we should stop at a breakpoint 116 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); 117 if (bp_site_sp) 118 { 119 StoppointCallbackContext context (event_ptr, 120 &m_thread.GetProcess(), 121 &m_thread, 122 m_thread.GetStackFrameAtIndex(0).get(), 123 true); 124 125 m_should_stop = bp_site_sp->ShouldStop (&context); 126 } 127 else 128 { 129 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 130 131 if (log) 132 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); 133 134 m_should_stop = true; 135 } 136 m_should_stop_is_valid = true; 137 } 138 return m_should_stop; 139 } 140 141 virtual void 142 PerformAction (Event *event_ptr) 143 { 144 if (!m_should_perform_action) 145 return; 146 m_should_perform_action = false; 147 148 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 149 // We're going to calculate whether we should stop or not in some way during the course of 150 // this code. So set the valid flag here. Also by default we're going to stop, so 151 // set that here too. 152 // m_should_stop_is_valid = true; 153 m_should_stop = true; 154 155 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); 156 if (bp_site_sp) 157 { 158 size_t num_owners = bp_site_sp->GetNumberOfOwners(); 159 160 // We only continue from the callbacks if ALL the callbacks want us to continue. 161 // However we want to run all the callbacks, except of course if one of them actually 162 // resumes the target. 163 // So we use stop_requested to track what we're were asked to do. 164 bool stop_requested = true; 165 for (size_t j = 0; j < num_owners; j++) 166 { 167 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j); 168 StoppointCallbackContext context (event_ptr, 169 &m_thread.GetProcess(), 170 &m_thread, 171 m_thread.GetStackFrameAtIndex(0).get(), 172 false); 173 stop_requested = bp_loc_sp->InvokeCallback (&context); 174 // Also make sure that the callback hasn't continued the target. 175 // If it did, when we'll set m_should_start to false and get out of here. 176 if (GetPrivateState() == eStateRunning) 177 m_should_stop = false; 178 } 179 180 if (m_should_stop && !stop_requested) 181 { 182 m_should_stop_is_valid = true; 183 m_should_stop = false; 184 } 185 186 // Okay, so now if all the callbacks say we should stop, let's try the Conditions: 187 if (m_should_stop) 188 { 189 size_t num_owners = bp_site_sp->GetNumberOfOwners(); 190 for (size_t j = 0; j < num_owners; j++) 191 { 192 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j); 193 if (bp_loc_sp->GetConditionText() != NULL) 194 { 195 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 196 // constructor errors up to the debugger's Async I/O. 197 198 StoppointCallbackContext context (event_ptr, 199 &m_thread.GetProcess(), 200 &m_thread, 201 m_thread.GetStackFrameAtIndex(0).get(), 202 false); 203 ValueObjectSP result_valobj_sp; 204 205 ExecutionResults result_code; 206 ValueObjectSP result_value_sp; 207 const bool discard_on_error = true; 208 Error error; 209 result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx, 210 eExecutionPolicyAlways, 211 discard_on_error, 212 bp_loc_sp->GetConditionText(), 213 NULL, 214 result_value_sp, 215 error); 216 if (result_code == eExecutionCompleted) 217 { 218 if (result_value_sp) 219 { 220 Scalar scalar_value; 221 if (result_value_sp->ResolveValue (scalar_value)) 222 { 223 if (scalar_value.ULongLong(1) == 0) 224 m_should_stop = false; 225 else 226 m_should_stop = true; 227 if (log) 228 log->Printf("Condition successfully evaluated, result is %s.\n", 229 m_should_stop ? "true" : "false"); 230 } 231 else 232 { 233 m_should_stop = true; 234 if (log) 235 log->Printf("Failed to get an integer result from the expression."); 236 } 237 } 238 } 239 else 240 { 241 Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger(); 242 StreamSP error_sp = debugger.GetAsyncErrorStream (); 243 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint "); 244 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 245 error_sp->Printf (": \"%s\"", 246 bp_loc_sp->GetConditionText()); 247 error_sp->EOL(); 248 const char *err_str = error.AsCString("<Unknown Error>"); 249 if (log) 250 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 251 252 error_sp->PutCString (err_str); 253 error_sp->EOL(); 254 error_sp->Flush(); 255 // If the condition fails to be parsed or run, we should stop. 256 m_should_stop = true; 257 } 258 } 259 260 // If any condition says we should stop, then we're going to stop, so we don't need 261 // to evaluate the others. 262 if (m_should_stop) 263 break; 264 } 265 } 266 } 267 else 268 { 269 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 270 271 if (log) 272 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); 273 } 274 if (log) 275 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 276 } 277 278 virtual bool 279 ShouldNotify (Event *event_ptr) 280 { 281 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); 282 if (bp_site_sp) 283 { 284 bool all_internal = true; 285 286 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++) 287 { 288 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) 289 { 290 all_internal = false; 291 break; 292 } 293 } 294 return all_internal == false; 295 } 296 return true; 297 } 298 299 virtual const char * 300 GetDescription () 301 { 302 if (m_description.empty()) 303 { 304 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); 305 if (bp_site_sp) 306 { 307 StreamString strm; 308 strm.Printf("breakpoint "); 309 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief); 310 m_description.swap (strm.GetString()); 311 } 312 else 313 { 314 StreamString strm; 315 if (m_address == LLDB_INVALID_ADDRESS) 316 strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value); 317 else 318 strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address); 319 m_description.swap (strm.GetString()); 320 } 321 } 322 return m_description.c_str(); 323 } 324 325 private: 326 std::string m_description; 327 bool m_should_stop; 328 bool m_should_stop_is_valid; 329 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions 330 // etc. behind the users backs, we need to make sure we only REALLY perform the action once. 331 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo, 332 // in case somebody deletes it between the time the StopInfo is made and the 333 // description is asked for. 334 }; 335 336 337 //---------------------------------------------------------------------- 338 // StopInfoWatchpoint 339 //---------------------------------------------------------------------- 340 341 class StopInfoWatchpoint : public StopInfo 342 { 343 public: 344 345 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) : 346 StopInfo(thread, watch_id), 347 m_description(), 348 m_should_stop(false), 349 m_should_stop_is_valid(false) 350 { 351 } 352 353 virtual ~StopInfoWatchpoint () 354 { 355 } 356 357 virtual StopReason 358 GetStopReason () const 359 { 360 return eStopReasonWatchpoint; 361 } 362 363 virtual bool 364 ShouldStop (Event *event_ptr) 365 { 366 // ShouldStop() method is idempotent and should not affect hit count. 367 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent() 368 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()-> 369 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()-> 370 // StopInfoWatchpoint::ShouldStop() and 371 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()-> 372 // StopInfoWatchpoint::PerformAction(). 373 if (m_should_stop_is_valid) 374 return m_should_stop; 375 376 WatchpointSP wp_sp = 377 m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue()); 378 if (wp_sp) 379 { 380 // Check if we should stop at a watchpoint. 381 StoppointCallbackContext context (event_ptr, 382 &m_thread.GetProcess(), 383 &m_thread, 384 m_thread.GetStackFrameAtIndex(0).get(), 385 true); 386 387 m_should_stop = wp_sp->ShouldStop (&context); 388 } 389 else 390 { 391 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 392 393 if (log) 394 log->Printf ("Process::%s could not find watchpoint location id: %lld...", 395 __FUNCTION__, GetValue()); 396 397 m_should_stop = true; 398 } 399 m_should_stop_is_valid = true; 400 return m_should_stop; 401 } 402 403 // Perform any action that is associated with this stop. This is done as the 404 // Event is removed from the event queue. 405 virtual void 406 PerformAction (Event *event_ptr) 407 { 408 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 409 // We're going to calculate if we should stop or not in some way during the course of 410 // this code. Also by default we're going to stop, so set that here. 411 m_should_stop = true; 412 413 WatchpointSP wp_sp = 414 m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue()); 415 if (wp_sp) 416 { 417 StoppointCallbackContext context (event_ptr, 418 &m_thread.GetProcess(), 419 &m_thread, 420 m_thread.GetStackFrameAtIndex(0).get(), 421 false); 422 bool stop_requested = wp_sp->InvokeCallback (&context); 423 // Also make sure that the callback hasn't continued the target. 424 // If it did, when we'll set m_should_start to false and get out of here. 425 if (GetPrivateState() == eStateRunning) 426 m_should_stop = false; 427 428 if (m_should_stop && !stop_requested) 429 { 430 // We have been vetoed. 431 m_should_stop = false; 432 } 433 434 if (m_should_stop && wp_sp->GetConditionText() != NULL) 435 { 436 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 437 // constructor errors up to the debugger's Async I/O. 438 StoppointCallbackContext context (event_ptr, 439 &m_thread.GetProcess(), 440 &m_thread, 441 m_thread.GetStackFrameAtIndex(0).get(), 442 false); 443 ExecutionResults result_code; 444 ValueObjectSP result_value_sp; 445 const bool discard_on_error = true; 446 Error error; 447 result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx, 448 eExecutionPolicyAlways, 449 discard_on_error, 450 wp_sp->GetConditionText(), 451 NULL, 452 result_value_sp, 453 error); 454 if (result_code == eExecutionCompleted) 455 { 456 if (result_value_sp) 457 { 458 Scalar scalar_value; 459 if (result_value_sp->ResolveValue (scalar_value)) 460 { 461 if (scalar_value.ULongLong(1) == 0) 462 { 463 // We have been vetoed. This takes precedence over querying 464 // the watchpoint whether it should stop (aka ignore count and 465 // friends). See also StopInfoWatchpoint::ShouldStop() as well 466 // as Process::ProcessEventData::DoOnRemoval(). 467 m_should_stop = false; 468 } 469 else 470 m_should_stop = true; 471 if (log) 472 log->Printf("Condition successfully evaluated, result is %s.\n", 473 m_should_stop ? "true" : "false"); 474 } 475 else 476 { 477 m_should_stop = true; 478 if (log) 479 log->Printf("Failed to get an integer result from the expression."); 480 } 481 } 482 } 483 else 484 { 485 Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger(); 486 StreamSP error_sp = debugger.GetAsyncErrorStream (); 487 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint "); 488 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 489 error_sp->Printf (": \"%s\"", 490 wp_sp->GetConditionText()); 491 error_sp->EOL(); 492 const char *err_str = error.AsCString("<Unknown Error>"); 493 if (log) 494 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 495 496 error_sp->PutCString (err_str); 497 error_sp->EOL(); 498 error_sp->Flush(); 499 // If the condition fails to be parsed or run, we should stop. 500 m_should_stop = true; 501 } 502 } 503 } 504 else 505 { 506 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 507 508 if (log) 509 log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value); 510 } 511 if (log) 512 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 513 } 514 515 virtual const char * 516 GetDescription () 517 { 518 if (m_description.empty()) 519 { 520 StreamString strm; 521 strm.Printf("watchpoint %lli", m_value); 522 m_description.swap (strm.GetString()); 523 } 524 return m_description.c_str(); 525 } 526 527 private: 528 std::string m_description; 529 bool m_should_stop; 530 bool m_should_stop_is_valid; 531 }; 532 533 534 535 //---------------------------------------------------------------------- 536 // StopInfoUnixSignal 537 //---------------------------------------------------------------------- 538 539 class StopInfoUnixSignal : public StopInfo 540 { 541 public: 542 543 StopInfoUnixSignal (Thread &thread, int signo) : 544 StopInfo (thread, signo) 545 { 546 } 547 548 virtual ~StopInfoUnixSignal () 549 { 550 } 551 552 553 virtual StopReason 554 GetStopReason () const 555 { 556 return eStopReasonSignal; 557 } 558 559 virtual bool 560 ShouldStop (Event *event_ptr) 561 { 562 return m_thread.GetProcess().GetUnixSignals().GetShouldStop (m_value); 563 } 564 565 566 // If should stop returns false, check if we should notify of this event 567 virtual bool 568 ShouldNotify (Event *event_ptr) 569 { 570 return m_thread.GetProcess().GetUnixSignals().GetShouldNotify (m_value); 571 } 572 573 574 virtual void 575 WillResume (lldb::StateType resume_state) 576 { 577 if (m_thread.GetProcess().GetUnixSignals().GetShouldSuppress(m_value) == false) 578 m_thread.SetResumeSignal(m_value); 579 } 580 581 virtual const char * 582 GetDescription () 583 { 584 if (m_description.empty()) 585 { 586 StreamString strm; 587 const char *signal_name = m_thread.GetProcess().GetUnixSignals().GetSignalAsCString (m_value); 588 if (signal_name) 589 strm.Printf("signal %s", signal_name); 590 else 591 strm.Printf("signal %lli", m_value); 592 m_description.swap (strm.GetString()); 593 } 594 return m_description.c_str(); 595 } 596 }; 597 598 //---------------------------------------------------------------------- 599 // StopInfoTrace 600 //---------------------------------------------------------------------- 601 602 class StopInfoTrace : public StopInfo 603 { 604 public: 605 606 StopInfoTrace (Thread &thread) : 607 StopInfo (thread, LLDB_INVALID_UID) 608 { 609 } 610 611 virtual ~StopInfoTrace () 612 { 613 } 614 615 virtual StopReason 616 GetStopReason () const 617 { 618 return eStopReasonTrace; 619 } 620 621 virtual const char * 622 GetDescription () 623 { 624 if (m_description.empty()) 625 return "trace"; 626 else 627 return m_description.c_str(); 628 } 629 }; 630 631 632 //---------------------------------------------------------------------- 633 // StopInfoException 634 //---------------------------------------------------------------------- 635 636 class StopInfoException : public StopInfo 637 { 638 public: 639 640 StopInfoException (Thread &thread, const char *description) : 641 StopInfo (thread, LLDB_INVALID_UID) 642 { 643 if (description) 644 SetDescription (description); 645 } 646 647 virtual 648 ~StopInfoException () 649 { 650 } 651 652 virtual StopReason 653 GetStopReason () const 654 { 655 return eStopReasonException; 656 } 657 658 virtual const char * 659 GetDescription () 660 { 661 if (m_description.empty()) 662 return "exception"; 663 else 664 return m_description.c_str(); 665 } 666 }; 667 668 669 //---------------------------------------------------------------------- 670 // StopInfoThreadPlan 671 //---------------------------------------------------------------------- 672 673 class StopInfoThreadPlan : public StopInfo 674 { 675 public: 676 677 StopInfoThreadPlan (ThreadPlanSP &plan_sp) : 678 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID), 679 m_plan_sp (plan_sp) 680 { 681 } 682 683 virtual ~StopInfoThreadPlan () 684 { 685 } 686 687 virtual StopReason 688 GetStopReason () const 689 { 690 return eStopReasonPlanComplete; 691 } 692 693 virtual const char * 694 GetDescription () 695 { 696 if (m_description.empty()) 697 { 698 StreamString strm; 699 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief); 700 m_description.swap (strm.GetString()); 701 } 702 return m_description.c_str(); 703 } 704 705 private: 706 ThreadPlanSP m_plan_sp; 707 }; 708 } // namespace lldb_private 709 710 StopInfoSP 711 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id) 712 { 713 return StopInfoSP (new StopInfoBreakpoint (thread, break_id)); 714 } 715 716 StopInfoSP 717 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop) 718 { 719 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop)); 720 } 721 722 StopInfoSP 723 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id) 724 { 725 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id)); 726 } 727 728 StopInfoSP 729 StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo) 730 { 731 return StopInfoSP (new StopInfoUnixSignal (thread, signo)); 732 } 733 734 StopInfoSP 735 StopInfo::CreateStopReasonToTrace (Thread &thread) 736 { 737 return StopInfoSP (new StopInfoTrace (thread)); 738 } 739 740 StopInfoSP 741 StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp) 742 { 743 return StopInfoSP (new StopInfoThreadPlan (plan_sp)); 744 } 745 746 StopInfoSP 747 StopInfo::CreateStopReasonWithException (Thread &thread, const char *description) 748 { 749 return StopInfoSP (new StopInfoException (thread, description)); 750 } 751