1 //===-- BreakpointLocation.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 // C Includes 11 // C++ Includes 12 #include <string> 13 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Breakpoint/BreakpointID.h" 18 #include "lldb/Breakpoint/StoppointCallbackContext.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/Log.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Target/ThreadPlan.h" 23 #include "lldb/Target/Process.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/lldb-private-log.h" 26 #include "lldb/Target/Thread.h" 27 #include "lldb/Target/ThreadSpec.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 BreakpointLocation::BreakpointLocation 33 ( 34 break_id_t loc_id, 35 Breakpoint &owner, 36 const Address &addr, 37 lldb::tid_t tid, 38 bool hardware 39 ) : 40 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware), 41 m_being_created(true), 42 m_address (addr), 43 m_owner (owner), 44 m_options_ap (), 45 m_bp_site_sp () 46 { 47 SetThreadID (tid); 48 m_being_created = false; 49 } 50 51 BreakpointLocation::~BreakpointLocation() 52 { 53 ClearBreakpointSite(); 54 } 55 56 lldb::addr_t 57 BreakpointLocation::GetLoadAddress () const 58 { 59 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); 60 } 61 62 Address & 63 BreakpointLocation::GetAddress () 64 { 65 return m_address; 66 } 67 68 Breakpoint & 69 BreakpointLocation::GetBreakpoint () 70 { 71 return m_owner; 72 } 73 74 bool 75 BreakpointLocation::IsEnabled () const 76 { 77 if (!m_owner.IsEnabled()) 78 return false; 79 else if (m_options_ap.get() != NULL) 80 return m_options_ap->IsEnabled(); 81 else 82 return true; 83 } 84 85 void 86 BreakpointLocation::SetEnabled (bool enabled) 87 { 88 GetLocationOptions()->SetEnabled(enabled); 89 if (enabled) 90 { 91 ResolveBreakpointSite(); 92 } 93 else 94 { 95 ClearBreakpointSite(); 96 } 97 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 98 } 99 100 void 101 BreakpointLocation::SetThreadID (lldb::tid_t thread_id) 102 { 103 if (thread_id != LLDB_INVALID_THREAD_ID) 104 GetLocationOptions()->SetThreadID(thread_id); 105 else 106 { 107 // If we're resetting this to an invalid thread id, then 108 // don't make an options pointer just to do that. 109 if (m_options_ap.get() != NULL) 110 m_options_ap->SetThreadID (thread_id); 111 } 112 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 113 } 114 115 lldb::tid_t 116 BreakpointLocation::GetThreadID () 117 { 118 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 119 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); 120 else 121 return LLDB_INVALID_THREAD_ID; 122 } 123 124 void 125 BreakpointLocation::SetThreadIndex (uint32_t index) 126 { 127 if (index != 0) 128 GetLocationOptions()->GetThreadSpec()->SetIndex(index); 129 else 130 { 131 // If we're resetting this to an invalid thread id, then 132 // don't make an options pointer just to do that. 133 if (m_options_ap.get() != NULL) 134 m_options_ap->GetThreadSpec()->SetIndex(index); 135 } 136 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 137 138 } 139 140 uint32_t 141 BreakpointLocation::GetThreadIndex() const 142 { 143 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 144 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); 145 else 146 return 0; 147 } 148 149 void 150 BreakpointLocation::SetThreadName (const char *thread_name) 151 { 152 if (thread_name != NULL) 153 GetLocationOptions()->GetThreadSpec()->SetName(thread_name); 154 else 155 { 156 // If we're resetting this to an invalid thread id, then 157 // don't make an options pointer just to do that. 158 if (m_options_ap.get() != NULL) 159 m_options_ap->GetThreadSpec()->SetName(thread_name); 160 } 161 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 162 } 163 164 const char * 165 BreakpointLocation::GetThreadName () const 166 { 167 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 168 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); 169 else 170 return NULL; 171 } 172 173 void 174 BreakpointLocation::SetQueueName (const char *queue_name) 175 { 176 if (queue_name != NULL) 177 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); 178 else 179 { 180 // If we're resetting this to an invalid thread id, then 181 // don't make an options pointer just to do that. 182 if (m_options_ap.get() != NULL) 183 m_options_ap->GetThreadSpec()->SetQueueName(queue_name); 184 } 185 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 186 } 187 188 const char * 189 BreakpointLocation::GetQueueName () const 190 { 191 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 192 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); 193 else 194 return NULL; 195 } 196 197 bool 198 BreakpointLocation::InvokeCallback (StoppointCallbackContext *context) 199 { 200 if (m_options_ap.get() != NULL && m_options_ap->HasCallback()) 201 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID()); 202 else 203 return m_owner.InvokeCallback (context, GetID()); 204 } 205 206 void 207 BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton, 208 bool is_synchronous) 209 { 210 // The default "Baton" class will keep a copy of "baton" and won't free 211 // or delete it when it goes goes out of scope. 212 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 213 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 214 } 215 216 void 217 BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp, 218 bool is_synchronous) 219 { 220 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous); 221 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 222 } 223 224 225 void 226 BreakpointLocation::ClearCallback () 227 { 228 GetLocationOptions()->ClearCallback(); 229 } 230 231 void 232 BreakpointLocation::SetCondition (const char *condition) 233 { 234 GetLocationOptions()->SetCondition (condition); 235 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); 236 } 237 238 const char * 239 BreakpointLocation::GetConditionText () const 240 { 241 return GetOptionsNoCreate()->GetConditionText(); 242 } 243 244 uint32_t 245 BreakpointLocation::GetIgnoreCount () 246 { 247 return GetOptionsNoCreate()->GetIgnoreCount(); 248 } 249 250 void 251 BreakpointLocation::SetIgnoreCount (uint32_t n) 252 { 253 GetLocationOptions()->SetIgnoreCount(n); 254 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 255 } 256 257 void 258 BreakpointLocation::DecrementIgnoreCount() 259 { 260 if (m_options_ap.get() != NULL) 261 { 262 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 263 if (loc_ignore != 0) 264 m_options_ap->SetIgnoreCount(loc_ignore - 1); 265 } 266 } 267 268 bool 269 BreakpointLocation::IgnoreCountShouldStop() 270 { 271 if (m_options_ap.get() != NULL) 272 { 273 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 274 if (loc_ignore != 0) 275 { 276 m_owner.DecrementIgnoreCount(); 277 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a 278 // chance to. 279 return false; 280 } 281 } 282 return true; 283 } 284 285 const BreakpointOptions * 286 BreakpointLocation::GetOptionsNoCreate () const 287 { 288 if (m_options_ap.get() != NULL) 289 return m_options_ap.get(); 290 else 291 return m_owner.GetOptions (); 292 } 293 294 BreakpointOptions * 295 BreakpointLocation::GetLocationOptions () 296 { 297 // If we make the copy we don't copy the callbacks because that is potentially 298 // expensive and we don't want to do that for the simple case where someone is 299 // just disabling the location. 300 if (m_options_ap.get() == NULL) 301 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); 302 303 return m_options_ap.get(); 304 } 305 306 bool 307 BreakpointLocation::ValidForThisThread (Thread *thread) 308 { 309 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); 310 } 311 312 // RETURNS - true if we should stop at this breakpoint, false if we 313 // should continue. Note, we don't check the thread spec for the breakpoint 314 // here, since if the breakpoint is not for this thread, then the event won't 315 // even get reported, so the check is redundant. 316 317 bool 318 BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 319 { 320 bool should_stop = true; 321 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 322 323 IncrementHitCount(); 324 325 if (!IsEnabled()) 326 return false; 327 328 if (!IgnoreCountShouldStop()) 329 return false; 330 331 if (!m_owner.IgnoreCountShouldStop()) 332 return false; 333 334 // We only run synchronous callbacks in ShouldStop: 335 context->is_synchronous = true; 336 should_stop = InvokeCallback (context); 337 338 if (log) 339 { 340 StreamString s; 341 GetDescription (&s, lldb::eDescriptionLevelVerbose); 342 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing"); 343 } 344 345 return should_stop; 346 } 347 348 bool 349 BreakpointLocation::IsResolved () const 350 { 351 return m_bp_site_sp.get() != NULL; 352 } 353 354 lldb::BreakpointSiteSP 355 BreakpointLocation::GetBreakpointSite() const 356 { 357 return m_bp_site_sp; 358 } 359 360 bool 361 BreakpointLocation::ResolveBreakpointSite () 362 { 363 if (m_bp_site_sp) 364 return true; 365 366 Process *process = m_owner.GetTarget().GetProcessSP().get(); 367 if (process == NULL) 368 return false; 369 370 if (m_owner.GetTarget().GetSectionLoadList().IsEmpty()) 371 return false; 372 373 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false); 374 375 if (new_id == LLDB_INVALID_BREAK_ID) 376 { 377 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 378 if (log) 379 log->Warning ("Tried to add breakpoint site at 0x%llx but it was already present.\n", 380 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); 381 return false; 382 } 383 384 return true; 385 } 386 387 bool 388 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) 389 { 390 m_bp_site_sp = bp_site_sp; 391 return true; 392 } 393 394 bool 395 BreakpointLocation::ClearBreakpointSite () 396 { 397 if (m_bp_site_sp.get()) 398 { 399 m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 400 GetID(), m_bp_site_sp); 401 m_bp_site_sp.reset(); 402 return true; 403 } 404 return false; 405 } 406 407 void 408 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) 409 { 410 SymbolContext sc; 411 s->Indent(); 412 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 413 414 if (level == lldb::eDescriptionLevelBrief) 415 return; 416 417 s->PutCString(": "); 418 419 if (level == lldb::eDescriptionLevelVerbose) 420 s->IndentMore(); 421 422 if (m_address.IsSectionOffset()) 423 { 424 m_address.CalculateSymbolContext(&sc); 425 426 if (level == lldb::eDescriptionLevelFull) 427 { 428 s->PutCString("where = "); 429 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); 430 } 431 else 432 { 433 if (sc.module_sp) 434 { 435 s->EOL(); 436 s->Indent("module = "); 437 sc.module_sp->GetFileSpec().Dump (s); 438 } 439 440 if (sc.comp_unit != NULL) 441 { 442 s->EOL(); 443 s->Indent("compile unit = "); 444 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); 445 446 if (sc.function != NULL) 447 { 448 s->EOL(); 449 s->Indent("function = "); 450 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>")); 451 } 452 453 if (sc.line_entry.line > 0) 454 { 455 s->EOL(); 456 s->Indent("location = "); 457 sc.line_entry.DumpStopContext (s, true); 458 } 459 460 } 461 else 462 { 463 // If we don't have a comp unit, see if we have a symbol we can print. 464 if (sc.symbol) 465 { 466 s->EOL(); 467 s->Indent("symbol = "); 468 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>")); 469 } 470 } 471 } 472 } 473 474 if (level == lldb::eDescriptionLevelVerbose) 475 { 476 s->EOL(); 477 s->Indent(); 478 } 479 s->Printf ("%saddress = ", (level == lldb::eDescriptionLevelFull && m_address.IsSectionOffset()) ? ", " : ""); 480 ExecutionContextScope *exe_scope = NULL; 481 Target *target = &m_owner.GetTarget(); 482 if (target) 483 exe_scope = target->GetProcessSP().get(); 484 if (exe_scope == NULL) 485 exe_scope = target; 486 487 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 488 489 if (level == lldb::eDescriptionLevelVerbose) 490 { 491 s->EOL(); 492 s->Indent(); 493 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); 494 495 s->Indent(); 496 s->Printf ("hit count = %-4u\n", GetHitCount()); 497 498 if (m_options_ap.get()) 499 { 500 s->Indent(); 501 m_options_ap->GetDescription (s, level); 502 s->EOL(); 503 } 504 s->IndentLess(); 505 } 506 else 507 { 508 s->Printf(", %sresolved, hit count = %u ", 509 (IsResolved() ? "" : "un"), 510 GetHitCount()); 511 if (m_options_ap.get()) 512 { 513 m_options_ap->GetDescription (s, level); 514 } 515 } 516 } 517 518 void 519 BreakpointLocation::Dump(Stream *s) const 520 { 521 if (s == NULL) 522 return; 523 524 s->Printf("BreakpointLocation %u: tid = %4.4llx load addr = 0x%8.8llx state = %s type = %s breakpoint " 525 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 526 GetID(), 527 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), 528 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), 529 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", 530 IsHardware() ? "hardware" : "software", 531 GetHardwareIndex(), 532 GetHitCount(), 533 GetOptionsNoCreate()->GetIgnoreCount()); 534 } 535 536 void 537 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) 538 { 539 if (!m_being_created 540 && !m_owner.IsInternal() 541 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 542 { 543 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 544 m_owner.shared_from_this()); 545 data->GetBreakpointLocationCollection().Add (shared_from_this()); 546 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 547 } 548 } 549 550