1 //===-- BreakpointResolverFileLine.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/Breakpoint/BreakpointResolverFileLine.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/Log.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Symbol/CompileUnit.h" 21 #include "lldb/Symbol/Function.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 //---------------------------------------------------------------------- 27 // BreakpointResolverFileLine: 28 //---------------------------------------------------------------------- 29 BreakpointResolverFileLine::BreakpointResolverFileLine 30 ( 31 Breakpoint *bkpt, 32 const FileSpec &file_spec, 33 uint32_t line_no, 34 lldb::addr_t offset, 35 bool check_inlines, 36 bool skip_prologue, 37 bool exact_match 38 ) : 39 BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver, offset), 40 m_file_spec (file_spec), 41 m_line_number (line_no), 42 m_inlines (check_inlines), 43 m_skip_prologue(skip_prologue), 44 m_exact_match(exact_match) 45 { 46 } 47 48 BreakpointResolverFileLine::~BreakpointResolverFileLine () 49 { 50 } 51 52 Searcher::CallbackReturn 53 BreakpointResolverFileLine::SearchCallback 54 ( 55 SearchFilter &filter, 56 SymbolContext &context, 57 Address *addr, 58 bool containing 59 ) 60 { 61 SymbolContextList sc_list; 62 63 assert (m_breakpoint != NULL); 64 65 // There is a tricky bit here. You can have two compilation units that #include the same file, and 66 // in one of them the function at m_line_number is used (and so code and a line entry for it is generated) but in the 67 // other it isn't. If we considered the CU's independently, then in the second inclusion, we'd move the breakpoint 68 // to the next function that actually generated code in the header file. That would end up being confusing. 69 // So instead, we do the CU iterations by hand here, then scan through the complete list of matches, and figure out 70 // the closest line number match, and only set breakpoints on that match. 71 72 // Note also that if file_spec only had a file name and not a directory, there may be many different file spec's in 73 // the resultant list. The closest line match for one will not be right for some totally different file. 74 // So we go through the match list and pull out the sets that have the same file spec in their line_entry 75 // and treat each set separately. 76 77 const size_t num_comp_units = context.module_sp->GetNumCompileUnits(); 78 for (size_t i = 0; i < num_comp_units; i++) 79 { 80 CompUnitSP cu_sp (context.module_sp->GetCompileUnitAtIndex (i)); 81 if (cu_sp) 82 { 83 if (filter.CompUnitPasses(*cu_sp)) 84 cu_sp->ResolveSymbolContext (m_file_spec, m_line_number, m_inlines, m_exact_match, eSymbolContextEverything, sc_list); 85 } 86 } 87 StreamString s; 88 s.Printf ("for %s:%d ", 89 m_file_spec.GetFilename().AsCString("<Unknown>"), 90 m_line_number); 91 92 SetSCMatchesByLine (filter, sc_list, m_skip_prologue, s.GetData()); 93 94 return Searcher::eCallbackReturnContinue; 95 } 96 97 Searcher::Depth 98 BreakpointResolverFileLine::GetDepth() 99 { 100 return Searcher::eDepthModule; 101 } 102 103 void 104 BreakpointResolverFileLine::GetDescription (Stream *s) 105 { 106 s->Printf ("file = '%s', line = %u, exact_match = %d", m_file_spec.GetPath().c_str(), m_line_number, m_exact_match); 107 } 108 109 void 110 BreakpointResolverFileLine::Dump (Stream *s) const 111 { 112 113 } 114 115 lldb::BreakpointResolverSP 116 BreakpointResolverFileLine::CopyForBreakpoint (Breakpoint &breakpoint) 117 { 118 lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(&breakpoint, 119 m_file_spec, 120 m_line_number, 121 m_offset, 122 m_inlines, 123 m_skip_prologue, 124 m_exact_match)); 125 126 return ret_sp; 127 } 128