diff --git a/lldb/include/lldb/Core/SearchFilter.h b/lldb/include/lldb/Core/SearchFilter.h --- a/lldb/include/lldb/Core/SearchFilter.h +++ b/lldb/include/lldb/Core/SearchFilter.h @@ -210,7 +210,8 @@ ByModule, ByModules, ByModulesAndCU, - LastKnownFilterType = ByModulesAndCU, + ByModuleListAndCUOrSupportFile, + LastKnownFilterType = ByModuleListAndCUOrSupportFile, UnknownFilter }; @@ -231,7 +232,13 @@ protected: // Serialization of SearchFilter options: - enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName }; + enum OptionNames { + ModList = 0, + CUList, + LanguageName, + CUOrSupportFileList, + LastOptionName + }; static const char *g_option_names[LastOptionName]; static const char *GetKey(enum OptionNames enum_value) { @@ -404,9 +411,10 @@ public: /// The basic constructor takes a Target, which gives the space to search, /// and the module list to restrict the search to. - SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP, - const FileSpecList &module_list, - const FileSpecList &cu_list); + SearchFilterByModuleListAndCU( + const lldb::TargetSP &targetSP, const FileSpecList &module_list, + const FileSpecList &cu_list, + enum FilterTy filter_ty = FilterTy::ByModulesAndCU); ~SearchFilterByModuleListAndCU() override; @@ -434,10 +442,32 @@ protected: lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; -private: +protected: FileSpecList m_cu_spec_list; }; +class SearchFilterByModuleListAndCUOrSupportFile + : public SearchFilterByModuleListAndCU { +public: + SearchFilterByModuleListAndCUOrSupportFile( + const lldb::TargetSP &targetSP, const FileSpecList &module_list, + const FileSpecList &cu_or_file_list); + + SearchFilterByModuleListAndCUOrSupportFile( + const SearchFilterByModuleListAndCUOrSupportFile &rhs); + + ~SearchFilterByModuleListAndCUOrSupportFile() override; + + bool AddressPasses(Address &address) override; + + uint32_t GetFilterRequiredItems() override; + + StructuredData::ObjectSP SerializeToStructuredData() override; + +protected: + lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; +}; + } // namespace lldb_private #endif // liblldb_SearchFilter_h_ diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -660,8 +660,8 @@ const std::vector &func_names, lldb::FunctionNameType func_name_type_mask, lldb::LanguageType language, lldb::addr_t m_offset, - LazyBool skip_prologue, bool internal, - bool request_hardware); + LazyBool skip_prologue, bool internal, bool request_hardware, + bool search_source_files); // Use this to create a general breakpoint: lldb::BreakpointSP CreateBreakpoint(lldb::SearchFilterSP &filter_sp, @@ -1236,6 +1236,10 @@ GetSearchFilterForModuleAndCUList(const FileSpecList *containingModules, const FileSpecList *containingSourceFiles); + lldb::SearchFilterSP GetSearchFilterForModuleListAndCUOrSupportFile( + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles); + lldb::REPLSP GetREPL(Status &err, lldb::LanguageType language, const char *repl_options, bool can_create); diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -248,6 +248,8 @@ // accelerate function lookup. At that point, we should switch the depth to // CompileUnit, and look in these tables. +#include "lldb/Symbol/CompileUnit.h" + Searcher::CallbackReturn BreakpointResolverName::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr) { @@ -268,6 +270,8 @@ } bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0; + bool filter_by_function = + (filter.GetFilterRequiredItems() & eSymbolContextFunction) != 0; bool filter_by_language = (m_language != eLanguageTypeUnknown); const bool include_symbols = !filter_by_cu; const bool include_inlines = true; @@ -312,8 +316,26 @@ SymbolContext sc; func_list.GetContextAtIndex(idx, sc); if (filter_by_cu) { - if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit)) - remove_it = true; + if (!filter_by_function) { + if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit)) + remove_it = true; + } else { + // TODO(kwk): Currently this appears somewhat like a hack because only + // the SearchFilterByModuleListAndCUOrSupportFile search filter + // requires eSymbolContextCompUnit and eSymbolContextFunction + // (filter_by_cu && filter_by_function). + + // Keep this symbol context if it is a function call to a function + // whose declaration is located in a file that passes. This is needed + // for inlined functions (e.g. when LTO is enabled) and templates. + if (Type *type = sc.function->GetType()) { + Declaration &decl = + const_cast(type->GetDeclaration()); + FileSpec &source_file = decl.GetFile(); + if (!filter.CompUnitPasses(source_file)) + remove_it = true; + } + } } if (filter_by_language) { @@ -335,64 +357,67 @@ // Remove any duplicates between the function list and the symbol list SymbolContext sc; - if (func_list.GetSize()) { - for (i = 0; i < func_list.GetSize(); i++) { - if (func_list.GetContextAtIndex(i, sc)) { - bool is_reexported = false; - - if (sc.block && sc.block->GetInlinedFunctionInfo()) { - if (!sc.block->GetStartAddress(break_addr)) - break_addr.Clear(); - } else if (sc.function) { - break_addr = sc.function->GetAddressRange().GetBaseAddress(); - if (m_skip_prologue && break_addr.IsValid()) { - const uint32_t prologue_byte_size = - sc.function->GetPrologueByteSize(); - if (prologue_byte_size) - break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); - } - } else if (sc.symbol) { - if (sc.symbol->GetType() == eSymbolTypeReExported) { - const Symbol *actual_symbol = - sc.symbol->ResolveReExportedSymbol(m_breakpoint->GetTarget()); - if (actual_symbol) { - is_reexported = true; - break_addr = actual_symbol->GetAddress(); - } - } else { - break_addr = sc.symbol->GetAddress(); - } - - if (m_skip_prologue && break_addr.IsValid()) { - const uint32_t prologue_byte_size = - sc.symbol->GetPrologueByteSize(); - if (prologue_byte_size) - break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); - else { - const Architecture *arch = - m_breakpoint->GetTarget().GetArchitecturePlugin(); - if (arch) - arch->AdjustBreakpointAddress(*sc.symbol, break_addr); - } - } + if (!func_list.GetSize()) + return Searcher::eCallbackReturnContinue; + + for (i = 0; i < func_list.GetSize(); i++) { + if (!func_list.GetContextAtIndex(i, sc)) + continue; + + bool is_reexported = false; + + if (sc.block && sc.block->GetInlinedFunctionInfo()) { + if (!sc.block->GetStartAddress(break_addr)) + break_addr.Clear(); + } else if (sc.function) { + break_addr = sc.function->GetAddressRange().GetBaseAddress(); + if (m_skip_prologue && break_addr.IsValid()) { + const uint32_t prologue_byte_size = + sc.function->GetPrologueByteSize(); + if (prologue_byte_size) + break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); + } + } else if (sc.symbol) { + if (sc.symbol->GetType() == eSymbolTypeReExported) { + const Symbol *actual_symbol = + sc.symbol->ResolveReExportedSymbol(m_breakpoint->GetTarget()); + if (actual_symbol) { + is_reexported = true; + break_addr = actual_symbol->GetAddress(); } + } else { + break_addr = sc.symbol->GetAddress(); + } - if (break_addr.IsValid()) { - if (filter.AddressPasses(break_addr)) { - BreakpointLocationSP bp_loc_sp( - AddLocation(break_addr, &new_location)); - bp_loc_sp->SetIsReExported(is_reexported); - if (bp_loc_sp && new_location && !m_breakpoint->IsInternal()) { - if (log) { - StreamString s; - bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - LLDB_LOGF(log, "Added location: %s\n", s.GetData()); - } - } - } + if (m_skip_prologue && break_addr.IsValid()) { + const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); + if (prologue_byte_size) + break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); + else { + const Architecture *arch = + m_breakpoint->GetTarget().GetArchitecturePlugin(); + if (arch) + arch->AdjustBreakpointAddress(*sc.symbol, break_addr); } } } + + if (!break_addr.IsValid()) + continue; + + if (!filter.AddressPasses(break_addr)) + continue; + + BreakpointLocationSP bp_loc_sp( + AddLocation(break_addr, &new_location)); + bp_loc_sp->SetIsReExported(is_reexported); + if (bp_loc_sp && new_location && !m_breakpoint->IsInternal()) { + if (log) { + StreamString s; + bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); + LLDB_LOGF(log, "Added location: %s\n", s.GetData()); + } + } } return Searcher::eCallbackReturnContinue; diff --git a/lldb/source/Breakpoint/CMakeLists.txt b/lldb/source/Breakpoint/CMakeLists.txt --- a/lldb/source/Breakpoint/CMakeLists.txt +++ b/lldb/source/Breakpoint/CMakeLists.txt @@ -13,6 +13,7 @@ BreakpointResolverAddress.cpp BreakpointResolverFileLine.cpp BreakpointResolverFileRegex.cpp +# BreakpointResolverDeclFileRegex.cpp BreakpointResolverName.cpp BreakpointResolverScripted.cpp BreakpointSite.cpp diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -444,6 +444,10 @@ m_source_regex_func_names.insert(std::string(option_arg)); break; + case 'Q': { + m_search_source_files = true; + } break; + default: llvm_unreachable("Unimplemented option"); } @@ -474,6 +478,7 @@ m_move_to_nearest_code = eLazyBoolCalculate; m_source_regex_func_names.clear(); m_current_key.clear(); + m_search_source_files = false; } llvm::ArrayRef GetDefinitions() override { @@ -505,6 +510,9 @@ LazyBool m_move_to_nearest_code; std::unordered_set m_source_regex_func_names; std::string m_current_key; + bool m_search_source_files; // When using -f or derivates make sure to + // always search all source files and not only + // compilation unit file names. }; protected: @@ -611,7 +619,7 @@ &(m_options.m_modules), &(m_options.m_filenames), m_options.m_func_names, name_type_mask, m_options.m_language, m_options.m_offset_addr, m_options.m_skip_prologue, internal, - m_options.m_hardware); + m_options.m_hardware, m_options.m_search_source_files); } break; case eSetTypeFunctionRegexp: // Breakpoint by regular expression function diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -196,6 +196,8 @@ Groups<[1, 9]>, Arg<"Boolean">, Desc<"Move breakpoints to nearest code. If not set the " "target.move-to-nearest-codesetting is used.">; + def breakpoint_set_search_source_files : Option<"search-source-files", "Q">, + Desc<"Always search all search files and not only compilation unit files when using -f or derivates.">; /* Don't add this option till it actually does something useful... def breakpoint_set_exception_typename : Option<"exception-typename", "O">, Arg<"TypeName">, Desc<"The breakpoint will only stop if an " diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -40,13 +40,14 @@ using namespace lldb; using namespace lldb_private; -const char *SearchFilter::g_ty_to_name[] = {"Unconstrained", "Exception", - "Module", "Modules", - "ModulesAndCU", "Unknown"}; +const char *SearchFilter::g_ty_to_name[] = { + "Unconstrained", "Exception", "Module", + "Modules", "ModulesAndCU", "ModulesAndCUOrSupportFile", + "Unknown"}; const char *SearchFilter::g_option_names[SearchFilter::OptionNames::LastOptionName] = { - "ModuleList", "CUList"}; + "ModuleList", "CUList", "CUOrSupportFileList"}; const char *SearchFilter::FilterTyToName(enum FilterTy type) { if (type > LastKnownFilterType) @@ -123,6 +124,11 @@ result_sp = SearchFilterByModuleListAndCU::CreateFromStructuredData( target, *subclass_options, error); break; + case ByModuleListAndCUOrSupportFile: + result_sp = + SearchFilterByModuleListAndCUOrSupportFile::CreateFromStructuredData( + target, *subclass_options, error); + break; case Exception: error.SetErrorString("Can't serialize exception breakpoints yet."); break; @@ -659,9 +665,9 @@ SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU( const lldb::TargetSP &target_sp, const FileSpecList &module_list, - const FileSpecList &cu_list) + const FileSpecList &cu_list, enum FilterTy filter_ty) : SearchFilterByModuleList(target_sp, module_list, - FilterTy::ByModulesAndCU), + filter_ty), m_cu_spec_list(cu_list) {} SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() = default; @@ -710,7 +716,7 @@ } return std::make_shared( - target.shared_from_this(), modules, cus); + target.shared_from_this(), modules, cus, FilterTy::ByModulesAndCU); } StructuredData::ObjectSP @@ -836,3 +842,61 @@ SearchFilterByModuleListAndCU::DoCopyForBreakpoint(Breakpoint &breakpoint) { return std::make_shared(*this); } + +// SearchFilterByModuleListAndCUOrSupportFile: + +SearchFilterByModuleListAndCUOrSupportFile:: + SearchFilterByModuleListAndCUOrSupportFile( + const lldb::TargetSP &target_sp, const FileSpecList &module_list, + const FileSpecList &cu_or_support_file_list) + : SearchFilterByModuleListAndCU(target_sp, module_list, + cu_or_support_file_list, + FilterTy::ByModuleListAndCUOrSupportFile) {} + +SearchFilterByModuleListAndCUOrSupportFile:: + SearchFilterByModuleListAndCUOrSupportFile( + const SearchFilterByModuleListAndCUOrSupportFile &rhs) = default; + +SearchFilterByModuleListAndCUOrSupportFile:: + ~SearchFilterByModuleListAndCUOrSupportFile() = default; + +StructuredData::ObjectSP +SearchFilterByModuleListAndCUOrSupportFile::SerializeToStructuredData() { + auto options_dict_sp = std::make_shared(); + SearchFilterByModuleList::SerializeUnwrapped(options_dict_sp); + SerializeFileSpecList(options_dict_sp, OptionNames::CUOrSupportFileList, + m_cu_spec_list); + return WrapOptionsDict(options_dict_sp); +} + +bool SearchFilterByModuleListAndCUOrSupportFile::AddressPasses( + Address &address) { + SymbolContext sym_ctx; + address.CalculateSymbolContext(&sym_ctx, eSymbolContextEverything); + if (!sym_ctx.comp_unit) { + if (m_cu_spec_list.GetSize() != 0) + return false; // Has no comp_unit so can't pass the file check. + } + FileSpec cu_spec; + if (sym_ctx.comp_unit) + cu_spec = sym_ctx.comp_unit->GetPrimaryFile(); + // If the primary source file associated with the symbol's compile unit is in + // the list of CU's or support files, that's enough. + // TODO(kwk): Is that enough? + if (m_cu_spec_list.FindFileIndex(0, cu_spec, false) != + UINT32_MAX) + return true; // Passes the file check (SearchFilterByModuleListAndCU returns true here) + return SearchFilterByModuleList::ModulePasses(sym_ctx.module_sp); +} + +uint32_t SearchFilterByModuleListAndCUOrSupportFile::GetFilterRequiredItems() { + return eSymbolContextModule | eSymbolContextCompUnit | eSymbolContextFunction; +} + +lldb::SearchFilterSP +SearchFilterByModuleListAndCUOrSupportFile::DoCopyForBreakpoint( + Breakpoint &breakpoint) { + return std::make_shared(*this); +} + + diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -350,7 +350,9 @@ 0, /* offset */ eLazyBoolNo, /* skip_prologue */ true, /* internal */ - false /* request_hardware */); + false, /* request_hardware */ + false /* search source files */ + ); } if (dyld_break->GetNumResolvedLocations() != 1) { diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -323,7 +323,7 @@ LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool hardware, - LazyBool move_to_nearest_code) { + LazyBool move_to_nearest_code) { FileSpec remapped_file; if (!GetSourcePathMap().ReverseRemapPath(file, remapped_file)) remapped_file = file; @@ -438,12 +438,18 @@ const std::vector &func_names, FunctionNameType func_name_type_mask, LanguageType language, lldb::addr_t offset, - LazyBool skip_prologue, bool internal, bool hardware) { + LazyBool skip_prologue, bool internal, bool hardware, + bool search_source_files) { BreakpointSP bp_sp; size_t num_names = func_names.size(); if (num_names > 0) { - SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( - containingModules, containingSourceFiles)); + SearchFilterSP filter_sp; + if (search_source_files) + filter_sp = GetSearchFilterForModuleListAndCUOrSupportFile( + containingModules, containingSourceFiles); + else + filter_sp = GetSearchFilterForModuleAndCUList(containingModules, + containingSourceFiles); if (skip_prologue == eLazyBoolCalculate) skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; @@ -544,6 +550,23 @@ return filter_sp; } +SearchFilterSP Target::GetSearchFilterForModuleListAndCUOrSupportFile( + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles) { + if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0) + return GetSearchFilterForModuleList(containingModules); + + SearchFilterSP filter_sp; + if (containingModules == nullptr) { + filter_sp = std::make_shared( + shared_from_this(), FileSpecList(), *containingSourceFiles); + } else { + filter_sp = std::make_shared( + shared_from_this(), *containingModules, *containingSourceFiles); + } + return filter_sp; +} + BreakpointSP Target::CreateFuncRegexBreakpoint( const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, RegularExpression func_regex, diff --git a/lldb/test/Shell/Breakpoint/Inputs/search-source-files.h b/lldb/test/Shell/Breakpoint/Inputs/search-source-files.h new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Breakpoint/Inputs/search-source-files.h @@ -0,0 +1 @@ +int inlined_42() { return 42; } diff --git a/lldb/test/Shell/Breakpoint/Inputs/search-source-files.cpp b/lldb/test/Shell/Breakpoint/Inputs/search-source-files.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Breakpoint/Inputs/search-source-files.cpp @@ -0,0 +1,7 @@ +#include "search-source-files.h" +#include "search-source-files2.h" + +int main(int argc, char *argv[]) { + int a = inlined_42(); + return return_zero() + a; +} diff --git a/lldb/test/Shell/Breakpoint/Inputs/search-source-files2.h b/lldb/test/Shell/Breakpoint/Inputs/search-source-files2.h new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Breakpoint/Inputs/search-source-files2.h @@ -0,0 +1 @@ +int return_zero() { return 0; } \ No newline at end of file diff --git a/lldb/test/Shell/Breakpoint/search-source-files.test b/lldb/test/Shell/Breakpoint/search-source-files.test new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Breakpoint/search-source-files.test @@ -0,0 +1,81 @@ +# In these tests we will set breakpoints on a function by name. That function +# is defined in a header file (search-source-files.h) and will therefore be +# inlined into the file that includes it (search-source-files.cpp). +# +# The change that goes along with this test file introduces a flag +# (--search-source-files or -Q) that you can pass to "(lldb) breakpoint set". +# We run several tests, each one time without and one time with this new +# parameter. That way we verify that LLDB's default behavior hasn't changed. +# +# TODO(kwk): Check that we can also do the same with C++ methods in files? +# (See https://lldb.llvm.org/use/tutorial.html and look for --method.) + +# RUN: mkdir -p %t +# RUN: cd %t +# RUN: %build %p/Inputs/search-source-files.cpp -o dummy.out +# RUN: %lldb -b -s %s dummy.out | FileCheck --color --dump-input=fail %s + +#--------------------------------- +# Set breakpoint by function name. +#--------------------------------- + +breakpoint set -n inlined_42 +# CHECK: (lldb) breakpoint set -n inlined_42 +# CHECK-NEXT: Breakpoint 1: where = dummy.out`inlined_42() + 4 at search-source-files.h:1:20, address = 0x0{{.*}} + +breakpoint set -n inlined_42 --search-source-files +# CHECK: (lldb) breakpoint set -n inlined_42 --search-source-files +# CHECK-NEXT: Breakpoint 2: where = dummy.out`inlined_42() + 4 at search-source-files.h:1:20, address = 0x0{{.*}} + +#---------------------------------------------------------------------- +# Set breakpoint by function name and filename +# (the one in which the function is inlined, aka the compilation unit). +#---------------------------------------------------------------------- + +breakpoint set -n inlined_42 -f search-source-files.cpp +# CHECK: (lldb) breakpoint set -n inlined_42 -f search-source-files.cpp +# CHECK-NEXT: Breakpoint 3: where = dummy.out`inlined_42() + 4 at search-source-files.h:1:20, address = 0x0{{.*}} + +breakpoint set -n inlined_42 -f search-source-files.cpp --search-source-files +# CHECK: (lldb) breakpoint set -n inlined_42 -f search-source-files.cpp --search-source-files +# CHECK-NEXT: Breakpoint 4: no locations (pending). + +#---------------------------------------------------- +# Set breakpoint by function name and source filename +# (the file in which the function is defined). +# +# NOTE: This test is the really interesting one as it +# shows that we can now search by source files +# that are themselves no compulation units when +# the --search-source-files parameter is given. +#---------------------------------------------------- + +breakpoint set -n inlined_42 -f search-source-files.h +# CHECK: (lldb) breakpoint set -n inlined_42 -f search-source-files.h +# CHECK-NEXT: Breakpoint 5: no locations (pending). +# CHECK-NEXT: WARNING: Unable to resolve breakpoint to any actual locations. + +breakpoint set -n inlined_42 -f search-source-files.h --search-source-files +# CHECK: (lldb) breakpoint set -n inlined_42 -f search-source-files.h --search-source-files +# CHECK-NEXT: Breakpoint 6: where = dummy.out`inlined_42() + 4 at search-source-files.h:1:20, address = 0x0{{.*}} + +#----------------------------------------------------- +# Set breakpoint by function name and source filename. +# This time the file doesn't exist. +# +# NOTE: This test exists in order to prove that +# --search-source-files doesn't widen the search +# space too much. When we search for a function +# in file that doesn't exist, we should get no +# results. +#----------------------------------------------------- + +breakpoint set -n inlined_42 -f file-not-existing.h +# CHECK: (lldb) breakpoint set -n inlined_42 -f file-not-existing.h +# CHECK-NEXT: Breakpoint 7: no locations (pending). +# CHECK-NEXT: WARNING: Unable to resolve breakpoint to any actual locations. + +breakpoint set -n inlined_42 -f file-not-existing.h --search-source-files +# CHECK: (lldb) breakpoint set -n inlined_42 -f file-not-existing.h --search-source-files +# CHECK-NEXT: Breakpoint 8: no locations (pending). +# CHECK-NEXT: WARNING: Unable to resolve breakpoint to any actual locations.