1 //===-- Breakpoint.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 11 // C Includes 12 // C++ Includes 13 // Other libraries and framework includes 14 // Project includes 15 16 #include "lldb/Core/Address.h" 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Breakpoint/BreakpointLocationCollection.h" 20 #include "lldb/Breakpoint/BreakpointResolver.h" 21 #include "lldb/Breakpoint/BreakpointResolverFileLine.h" 22 #include "lldb/Core/Log.h" 23 #include "lldb/Core/ModuleList.h" 24 #include "lldb/Core/SearchFilter.h" 25 #include "lldb/Core/Stream.h" 26 #include "lldb/Core/StreamString.h" 27 #include "lldb/Symbol/SymbolContext.h" 28 #include "lldb/Target/Target.h" 29 #include "lldb/Target/ThreadSpec.h" 30 #include "lldb/lldb-private-log.h" 31 #include "llvm/Support/Casting.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 using namespace llvm; 36 37 const ConstString & 38 Breakpoint::GetEventIdentifier () 39 { 40 static ConstString g_identifier("event-identifier.breakpoint.changed"); 41 return g_identifier; 42 } 43 44 //---------------------------------------------------------------------- 45 // Breakpoint constructor 46 //---------------------------------------------------------------------- 47 Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) : 48 m_target (target), 49 m_filter_sp (filter_sp), 50 m_resolver_sp (resolver_sp), 51 m_options (), 52 m_locations () 53 { 54 } 55 56 //---------------------------------------------------------------------- 57 // Destructor 58 //---------------------------------------------------------------------- 59 Breakpoint::~Breakpoint() 60 { 61 } 62 63 bool 64 Breakpoint::IsInternal () const 65 { 66 return LLDB_BREAK_ID_IS_INTERNAL(m_bid); 67 } 68 69 70 71 Target& 72 Breakpoint::GetTarget () 73 { 74 return m_target; 75 } 76 77 const Target& 78 Breakpoint::GetTarget () const 79 { 80 return m_target; 81 } 82 83 BreakpointLocationSP 84 Breakpoint::AddLocation (const Address &addr, bool *new_location) 85 { 86 if (new_location) 87 *new_location = false; 88 BreakpointLocationSP bp_loc_sp (m_locations.FindByAddress(addr)); 89 if (!bp_loc_sp) 90 { 91 bp_loc_sp = m_locations.Create (*this, addr); 92 if (bp_loc_sp) 93 { 94 bp_loc_sp->ResolveBreakpointSite(); 95 96 if (new_location) 97 *new_location = true; 98 } 99 } 100 return bp_loc_sp; 101 } 102 103 BreakpointLocationSP 104 Breakpoint::FindLocationByAddress (const Address &addr) 105 { 106 return m_locations.FindByAddress(addr); 107 } 108 109 break_id_t 110 Breakpoint::FindLocationIDByAddress (const Address &addr) 111 { 112 return m_locations.FindIDByAddress(addr); 113 } 114 115 BreakpointLocationSP 116 Breakpoint::FindLocationByID (break_id_t bp_loc_id) 117 { 118 return m_locations.FindByID(bp_loc_id); 119 } 120 121 BreakpointLocationSP 122 Breakpoint::GetLocationAtIndex (uint32_t index) 123 { 124 return m_locations.GetByIndex(index); 125 } 126 127 BreakpointLocationSP 128 Breakpoint::GetLocationSP (BreakpointLocation *bp_loc_ptr) 129 { 130 return m_locations.FindByID(bp_loc_ptr->GetID()); 131 } 132 133 134 // For each of the overall options we need to decide how they propagate to 135 // the location options. This will determine the precedence of options on 136 // the breakpoint vrs. its locations. 137 138 // Disable at the breakpoint level should override the location settings. 139 // That way you can conveniently turn off a whole breakpoint without messing 140 // up the individual settings. 141 142 void 143 Breakpoint::SetEnabled (bool enable) 144 { 145 m_options.SetEnabled(enable); 146 if (enable) 147 m_locations.ResolveAllBreakpointSites(); 148 else 149 m_locations.ClearAllBreakpointSites(); 150 } 151 152 bool 153 Breakpoint::IsEnabled () 154 { 155 return m_options.IsEnabled(); 156 } 157 158 void 159 Breakpoint::SetIgnoreCount (uint32_t n) 160 { 161 m_options.SetIgnoreCount(n); 162 } 163 164 uint32_t 165 Breakpoint::GetIgnoreCount () const 166 { 167 return m_options.GetIgnoreCount(); 168 } 169 170 uint32_t 171 Breakpoint::GetHitCount () const 172 { 173 return m_locations.GetHitCount(); 174 } 175 176 void 177 Breakpoint::SetThreadID (lldb::tid_t thread_id) 178 { 179 m_options.GetThreadSpec()->SetTID(thread_id); 180 } 181 182 lldb::tid_t 183 Breakpoint::GetThreadID () 184 { 185 if (m_options.GetThreadSpec() == NULL) 186 return LLDB_INVALID_THREAD_ID; 187 else 188 return m_options.GetThreadSpec()->GetTID(); 189 } 190 191 void 192 Breakpoint::SetCondition (const char *condition) 193 { 194 m_options.SetCondition (condition); 195 } 196 197 ThreadPlan * 198 Breakpoint::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, lldb::BreakpointLocationSP loc_sp, Stream &error) 199 { 200 return m_options.GetThreadPlanToTestCondition (exe_ctx, loc_sp, error); 201 } 202 203 const char * 204 Breakpoint::GetConditionText () 205 { 206 return m_options.GetConditionText(); 207 } 208 209 // This function is used when "baton" doesn't need to be freed 210 void 211 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous) 212 { 213 // The default "Baton" class will keep a copy of "baton" and won't free 214 // or delete it when it goes goes out of scope. 215 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 216 } 217 218 // This function is used when a baton needs to be freed and therefore is 219 // contained in a "Baton" subclass. 220 void 221 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous) 222 { 223 m_options.SetCallback(callback, callback_baton_sp, is_synchronous); 224 } 225 226 void 227 Breakpoint::ClearCallback () 228 { 229 m_options.ClearCallback (); 230 } 231 232 bool 233 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id) 234 { 235 return m_options.InvokeCallback (context, GetID(), bp_loc_id); 236 } 237 238 BreakpointOptions * 239 Breakpoint::GetOptions () 240 { 241 return &m_options; 242 } 243 244 void 245 Breakpoint::ResolveBreakpoint () 246 { 247 if (m_resolver_sp) 248 m_resolver_sp->ResolveBreakpoint(*m_filter_sp); 249 } 250 251 void 252 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list) 253 { 254 if (m_resolver_sp) 255 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); 256 } 257 258 void 259 Breakpoint::ClearAllBreakpointSites () 260 { 261 m_locations.ClearAllBreakpointSites(); 262 } 263 264 //---------------------------------------------------------------------- 265 // ModulesChanged: Pass in a list of new modules, and 266 //---------------------------------------------------------------------- 267 268 void 269 Breakpoint::ModulesChanged (ModuleList &module_list, bool load) 270 { 271 if (load) 272 { 273 // The logic for handling new modules is: 274 // 1) If the filter rejects this module, then skip it. 275 // 2) Run through the current location list and if there are any locations 276 // for that module, we mark the module as "seen" and we don't try to re-resolve 277 // breakpoint locations for that module. 278 // However, we do add breakpoint sites to these locations if needed. 279 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules. 280 281 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve 282 // them after the locations pass. Have to do it this way because 283 // resolving breakpoints will add new locations potentially. 284 285 const size_t num_locs = m_locations.GetSize(); 286 287 for (size_t i = 0; i < module_list.GetSize(); i++) 288 { 289 bool seen = false; 290 ModuleSP module_sp (module_list.GetModuleAtIndex (i)); 291 if (!m_filter_sp->ModulePasses (module_sp)) 292 continue; 293 294 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++) 295 { 296 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); 297 if (!break_loc->IsEnabled()) 298 continue; 299 const Section *section = break_loc->GetAddress().GetSection(); 300 if (section == NULL || section->GetModule() == module_sp.get()) 301 { 302 if (!seen) 303 seen = true; 304 305 if (!break_loc->ResolveBreakpointSite()) 306 { 307 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 308 if (log) 309 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", 310 break_loc->GetID(), GetID()); 311 } 312 } 313 } 314 315 if (!seen) 316 new_modules.AppendIfNeeded (module_sp); 317 318 } 319 if (new_modules.GetSize() > 0) 320 { 321 ResolveBreakpointInModules(new_modules); 322 } 323 } 324 else 325 { 326 // Go through the currently set locations and if any have breakpoints in 327 // the module list, then remove their breakpoint sites. 328 // FIXME: Think about this... Maybe it's better to delete the locations? 329 // Are we sure that on load-unload-reload the module pointer will remain 330 // the same? Or do we need to do an equality on modules that is an 331 // "equivalence"??? 332 333 for (size_t i = 0; i < module_list.GetSize(); i++) 334 { 335 ModuleSP module_sp (module_list.GetModuleAtIndex (i)); 336 if (m_filter_sp->ModulePasses (module_sp)) 337 { 338 const size_t num_locs = m_locations.GetSize(); 339 for (size_t loc_idx = 0; loc_idx < num_locs; ++loc_idx) 340 { 341 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); 342 const Section *section = break_loc->GetAddress().GetSection(); 343 if (section && section->GetModule() == module_sp.get()) 344 { 345 // Remove this breakpoint since the shared library is 346 // unloaded, but keep the breakpoint location around 347 // so we always get complete hit count and breakpoint 348 // lifetime info 349 break_loc->ClearBreakpointSite(); 350 } 351 } 352 } 353 } 354 } 355 } 356 357 void 358 Breakpoint::Dump (Stream *) 359 { 360 } 361 362 size_t 363 Breakpoint::GetNumResolvedLocations() const 364 { 365 // Return the number of breakpoints that are actually resolved and set 366 // down in the inferior process. 367 return m_locations.GetNumResolvedLocations(); 368 } 369 370 size_t 371 Breakpoint::GetNumLocations() const 372 { 373 return m_locations.GetSize(); 374 } 375 376 void 377 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) 378 { 379 assert (s != NULL); 380 s->Printf("%i: ", GetID()); 381 GetResolverDescription (s); 382 GetFilterDescription (s); 383 384 const size_t num_locations = GetNumLocations (); 385 const size_t num_resolved_locations = GetNumResolvedLocations (); 386 387 switch (level) 388 { 389 case lldb::eDescriptionLevelBrief: 390 case lldb::eDescriptionLevelFull: 391 if (num_locations > 0) 392 { 393 s->Printf(", locations = %zu", num_locations); 394 if (num_resolved_locations > 0) 395 s->Printf(", resolved = %zu", num_resolved_locations); 396 } 397 else 398 { 399 s->Printf(", locations = 0 (pending)"); 400 } 401 402 GetOptions()->GetDescription(s, level); 403 404 if (level == lldb::eDescriptionLevelFull) 405 { 406 s->IndentLess(); 407 s->EOL(); 408 } 409 break; 410 411 case lldb::eDescriptionLevelVerbose: 412 // Verbose mode does a debug dump of the breakpoint 413 Dump (s); 414 s->EOL (); 415 //s->Indent(); 416 GetOptions()->GetDescription(s, level); 417 break; 418 419 default: 420 break; 421 } 422 423 // The brief description is just the location name (1.2 or whatever). That's pointless to 424 // show in the breakpoint's description, so suppress it. 425 if (show_locations && level != lldb::eDescriptionLevelBrief) 426 { 427 s->IndentMore(); 428 for (size_t i = 0; i < num_locations; ++i) 429 { 430 BreakpointLocation *loc = GetLocationAtIndex(i).get(); 431 loc->GetDescription(s, level); 432 s->EOL(); 433 } 434 s->IndentLess(); 435 } 436 } 437 438 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type, 439 BreakpointSP &new_breakpoint_sp) : 440 EventData (), 441 m_breakpoint_event (sub_type), 442 m_new_breakpoint_sp (new_breakpoint_sp) 443 { 444 } 445 446 Breakpoint::BreakpointEventData::~BreakpointEventData () 447 { 448 } 449 450 const ConstString & 451 Breakpoint::BreakpointEventData::GetFlavorString () 452 { 453 static ConstString g_flavor ("Breakpoint::BreakpointEventData"); 454 return g_flavor; 455 } 456 457 const ConstString & 458 Breakpoint::BreakpointEventData::GetFlavor () const 459 { 460 return BreakpointEventData::GetFlavorString (); 461 } 462 463 464 BreakpointSP & 465 Breakpoint::BreakpointEventData::GetBreakpoint () 466 { 467 return m_new_breakpoint_sp; 468 } 469 470 BreakpointEventType 471 Breakpoint::BreakpointEventData::GetBreakpointEventType () const 472 { 473 return m_breakpoint_event; 474 } 475 476 void 477 Breakpoint::BreakpointEventData::Dump (Stream *s) const 478 { 479 } 480 481 Breakpoint::BreakpointEventData * 482 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const EventSP &event_sp) 483 { 484 if (event_sp) 485 { 486 EventData *event_data = event_sp->GetData(); 487 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString()) 488 return static_cast <BreakpointEventData *> (event_sp->GetData()); 489 } 490 return NULL; 491 } 492 493 BreakpointEventType 494 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp) 495 { 496 BreakpointEventData *data = GetEventDataFromEvent (event_sp); 497 498 if (data == NULL) 499 return eBreakpointEventTypeInvalidType; 500 else 501 return data->GetBreakpointEventType(); 502 } 503 504 BreakpointSP 505 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp) 506 { 507 BreakpointSP bp_sp; 508 509 BreakpointEventData *data = GetEventDataFromEvent (event_sp); 510 if (data) 511 bp_sp = data->GetBreakpoint(); 512 513 return bp_sp; 514 } 515 516 lldb::BreakpointLocationSP 517 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx) 518 { 519 lldb::BreakpointLocationSP bp_loc_sp; 520 521 BreakpointEventData *data = GetEventDataFromEvent (event_sp); 522 if (data) 523 { 524 Breakpoint *bp = data->GetBreakpoint().get(); 525 if (bp) 526 bp_loc_sp = bp->GetLocationAtIndex(bp_loc_idx); 527 } 528 529 return bp_loc_sp; 530 } 531 532 533 void 534 Breakpoint::GetResolverDescription (Stream *s) 535 { 536 if (m_resolver_sp) 537 m_resolver_sp->GetDescription (s); 538 } 539 540 541 bool 542 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll) 543 { 544 // TODO: To be correct, this method needs to fill the breakpoint location collection 545 // with the location IDs which match the filename and line_number. 546 // 547 548 if (m_resolver_sp) 549 { 550 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); 551 if (resolverFileLine && 552 resolverFileLine->m_file_spec.GetFilename() == filename && 553 resolverFileLine->m_line_number == line_number) 554 { 555 return true; 556 } 557 } 558 return false; 559 } 560 561 void 562 Breakpoint::GetFilterDescription (Stream *s) 563 { 564 m_filter_sp->GetDescription (s); 565 } 566 567 const BreakpointSP 568 Breakpoint::GetSP () 569 { 570 return m_target.GetBreakpointList().FindBreakpointByID (GetID()); 571 } 572