1 //===-- BreakpointResolverFileRegex.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/BreakpointResolverFileRegex.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/SourceManager.h" 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/lldb-private-log.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 //---------------------------------------------------------------------- 27 // BreakpointResolverFileRegex: 28 //---------------------------------------------------------------------- 29 BreakpointResolverFileRegex::BreakpointResolverFileRegex 30 ( 31 Breakpoint *bkpt, 32 RegularExpression ®ex 33 ) : 34 BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver), 35 m_regex (regex) 36 { 37 } 38 39 BreakpointResolverFileRegex::~BreakpointResolverFileRegex () 40 { 41 } 42 43 Searcher::CallbackReturn 44 BreakpointResolverFileRegex::SearchCallback 45 ( 46 SearchFilter &filter, 47 SymbolContext &context, 48 Address *addr, 49 bool containing 50 ) 51 { 52 53 assert (m_breakpoint != NULL); 54 if (!context.target_sp) 55 return eCallbackReturnContinue; 56 57 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 58 59 CompileUnit *cu = context.comp_unit; 60 FileSpec cu_file_spec = *(static_cast<FileSpec *>(cu)); 61 std::vector<uint32_t> line_matches; 62 context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches); 63 uint32_t num_matches = line_matches.size(); 64 for (int i = 0; i < num_matches; i++) 65 { 66 uint32_t start_idx = 0; 67 bool exact = false; 68 while (1) 69 { 70 LineEntry line_entry; 71 72 // Cycle through all the line entries that might match this one: 73 start_idx = cu->FindLineEntry (start_idx, line_matches[i], NULL, exact, &line_entry); 74 if (start_idx == UINT32_MAX) 75 break; 76 exact = true; 77 start_idx++; 78 79 Address line_start = line_entry.range.GetBaseAddress(); 80 if (line_start.IsValid()) 81 { 82 if (filter.AddressPasses(line_start)) 83 { 84 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start)); 85 if (log && bp_loc_sp && !m_breakpoint->IsInternal()) 86 { 87 StreamString s; 88 bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose); 89 log->Printf ("Added location: %s\n", s.GetData()); 90 } 91 } 92 else if (log) 93 { 94 log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass filter.\n", 95 line_start.GetFileAddress(), 96 cu_file_spec.GetFilename().AsCString("<Unknown>"), 97 line_matches[i]); 98 } 99 } 100 else 101 { 102 if (log) 103 log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n", 104 line_start.GetFileAddress(), 105 cu_file_spec.GetFilename().AsCString("<Unknown>"), 106 line_matches[i]); 107 } 108 109 } 110 } 111 assert (m_breakpoint != NULL); 112 113 return Searcher::eCallbackReturnContinue; 114 } 115 116 Searcher::Depth 117 BreakpointResolverFileRegex::GetDepth() 118 { 119 return Searcher::eDepthCompUnit; 120 } 121 122 void 123 BreakpointResolverFileRegex::GetDescription (Stream *s) 124 { 125 s->Printf ("source regex = \"%s\"", m_regex.GetText()); 126 } 127 128 void 129 BreakpointResolverFileRegex::Dump (Stream *s) const 130 { 131 132 } 133 134