BreakpointResolverFileLine.cpp revision c705730b96ede40118fc7b06d2807e9a4e503139
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- BreakpointResolverFileLine.cpp --------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Breakpoint/BreakpointResolverFileLine.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Breakpoint/BreakpointLocation.h" 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/StreamString.h" 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h" 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// BreakpointResolverFileLine: 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBreakpointResolverFileLine::BreakpointResolverFileLine 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Breakpoint *bkpt, 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t line_no, 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool check_inlines 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) : 34a62ad7c886252a08d614a2b391d0774a151b7196Johnny Chen BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver), 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file_spec (file_spec), 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_line_number (line_no), 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_inlines (check_inlines) 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBreakpointResolverFileLine::~BreakpointResolverFileLine () 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSearcher::CallbackReturn 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBreakpointResolverFileLine::SearchCallback 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SearchFilter &filter, 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolContext &context, 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Address *addr, 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool containing 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolContextList sc_list; 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (m_breakpoint != NULL); 57e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 58a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 59a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // There is a tricky bit here. You can have two compilation units that #include the same file, and 60a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // 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 61a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // other it isn't. If we considered the CU's independently, then in the second inclusion, we'd move the breakpoint 62a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // to the next function that actually generated code in the header file. That would end up being confusing. 63a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // So instead, we do the CU iterations by hand here, then scan through the complete list of matches, and figure out 64a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // the closest line number match, and only set breakpoints on that match. 65a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 66a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // Note also that if file_spec only had a file name and not a directory, there may be many different file spec's in 67a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // the resultant list. The closest line match for one will not be right for some totally different file. 68a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // So we go through the match list and pull out the sets that have the same file spec in their line_entry 69a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // and treat each set separately. 70a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 71a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham uint32_t num_comp_units = context.module_sp->GetNumCompileUnits(); 72a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham for (uint32_t i = 0; i < num_comp_units; i++) 73a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 74a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham CompUnitSP cu_sp (context.module_sp->GetCompileUnitAtIndex (i)); 75c705730b96ede40118fc7b06d2807e9a4e503139Greg Clayton if (cu_sp) 76c705730b96ede40118fc7b06d2807e9a4e503139Greg Clayton { 77c705730b96ede40118fc7b06d2807e9a4e503139Greg Clayton if (filter.CompUnitPasses(*cu_sp)) 78c705730b96ede40118fc7b06d2807e9a4e503139Greg Clayton cu_sp->ResolveSymbolContext (m_file_spec, m_line_number, m_inlines, false, eSymbolContextEverything, sc_list); 79c705730b96ede40118fc7b06d2807e9a4e503139Greg Clayton } 80a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 81a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 82a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham while (sc_list.GetSize() > 0) 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 84a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham SymbolContextList tmp_sc_list; 85a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham int current_idx = 0; 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolContext sc; 87a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham bool first_entry = true; 88a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 89a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham FileSpec match_file_spec; 90a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham uint32_t closest_line_number = UINT32_MAX; 91a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 92a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // Pull out the first entry, and all the others that match its file spec, and stuff them in the tmp list. 93a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham while (current_idx < sc_list.GetSize()) 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 95a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham bool matches; 96a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 97a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham sc_list.GetContextAtIndex (current_idx, sc); 98a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (first_entry) 99a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 100a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham match_file_spec = sc.line_entry.file; 101a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham matches = true; 102a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham first_entry = false; 103a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 104a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham else 105a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham matches = (sc.line_entry.file == match_file_spec); 106a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 107a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (matches) 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 109a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham tmp_sc_list.Append (sc); 110a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham sc_list.RemoveContextAtIndex(current_idx); 111a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 112a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // ResolveSymbolContext will always return a number that is >= the line number you pass in. 113a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // So the smaller line number is always better. 114a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (sc.line_entry.line < closest_line_number) 115a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham closest_line_number = sc.line_entry.line; 116a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 117a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham else 118a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham current_idx++; 119a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 120a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 121a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // Okay, we've found the closest line number match, now throw away all the others, 122a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham // and make breakpoints out of the closest line number match. 123a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 124a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham uint32_t tmp_sc_list_size = tmp_sc_list.GetSize(); 125a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 126a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham for (uint32_t i = 0; i < tmp_sc_list_size; i++) 127a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 128a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham SymbolContext sc; 129a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (tmp_sc_list.GetContextAtIndex(i, sc)) 130a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 131a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (sc.line_entry.line == closest_line_number) 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 133a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham Address line_start = sc.line_entry.range.GetBaseAddress(); 134a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (line_start.IsValid()) 13503c8ee5aeafcd6c43f10002a4f8096af01780f86Jim Ingham { 136a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (filter.AddressPasses(line_start)) 137a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 138a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start)); 139a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (log && bp_loc_sp && !m_breakpoint->IsInternal()) 140a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 141a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham StreamString s; 142a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose); 143a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham log->Printf ("Added location: %s\n", s.GetData()); 144a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 145a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 146a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham else if (log) 147a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 148a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass the filter.\n", 149a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham line_start.GetFileAddress(), 150a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham m_file_spec.GetFilename().AsCString("<Unknown>"), 151a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham m_line_number); 152a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 153a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham } 154a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham else 155a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham { 156a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (log) 157a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n", 158a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham line_start.GetFileAddress(), 159a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham m_file_spec.GetFilename().AsCString("<Unknown>"), 160a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham m_line_number); 16103c8ee5aeafcd6c43f10002a4f8096af01780f86Jim Ingham } 16203c8ee5aeafcd6c43f10002a4f8096af01780f86Jim Ingham } 163a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham else 16403c8ee5aeafcd6c43f10002a4f8096af01780f86Jim Ingham { 165a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham #if 0 166a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham s << "error: Breakpoint at '" << pos->c_str() << "' isn't resolved yet: \n"; 167a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (sc.line_entry.address.Dump(&s, Address::DumpStyleSectionNameOffset)) 168a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham s.EOL(); 169a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (sc.line_entry.address.Dump(&s, Address::DumpStyleSectionPointerOffset)) 170a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham s.EOL(); 171a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (sc.line_entry.address.Dump(&s, Address::DumpStyleFileAddress)) 172a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham s.EOL(); 173a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham if (sc.line_entry.address.Dump(&s, Address::DumpStyleLoadAddress)) 174a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham s.EOL(); 175a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham #endif 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 180a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return Searcher::eCallbackReturnContinue; 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSearcher::Depth 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBreakpointResolverFileLine::GetDepth() 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 187a44297a3a58c46fe88a37e3de18ce97c4c85edc5Jim Ingham return Searcher::eDepthModule; 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBreakpointResolverFileLine::GetDescription (Stream *s) 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 19312bec71b323dc520f0e985a86e09c4712559e115Greg Clayton s->Printf ("file ='%s', line = %u", m_file_spec.GetFilename().AsCString(), m_line_number); 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBreakpointResolverFileLine::Dump (Stream *s) const 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 202