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