--- /dev/null
+int main() {
+ int x = 47; // REGEX-THIS
+ return x;
+}
--- /dev/null
+# REQUIRES: windows
+#
+# RUN: %cc %p/Inputs/case-sensitive.c -g -o %t
+# RUN: lldb-test breakpoints %t %s | FileCheck %s
+
+breakpoint set -f case-sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f case-sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f %p/Inputs/case-sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f {{.*}}/Inputs/case-sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f %p/INPUTS/case-sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/case-sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f Case-Sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f Case-Sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f %p/INPUTS/Case-Sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/Case-Sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f case-sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f case-sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
+
+breakpoint set -f %p/Inputs/case-sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f {{.*}}/Inputs/case-sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
+
+breakpoint set -f %p/INPUTS/case-sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/case-sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
+
+breakpoint set -f Case-Sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f Case-Sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
+
+breakpoint set -f %p/INPUTS/Case-Sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/Case-Sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
--- /dev/null
+# REQUIRES: nowindows
+#
+# RUN: %cc %p/Inputs/case-sensitive.c -g -o %t
+# RUN: lldb-test breakpoints %t %s | FileCheck %s
+
+breakpoint set -f case-sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f case-sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f %p/Inputs/case-sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f {{.*}}/Inputs/case-sensitive.c -l 3
+# CHECK: At least one location.
+
+breakpoint set -f %p/INPUTS/case-sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/case-sensitive.c -l 3
+# CHECK: 0 locations.
+
+breakpoint set -f Case-Sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f Case-Sensitive.c -l 3
+# CHECK: 0 locations.
+
+breakpoint set -f %p/INPUTS/Case-Sensitive.c -l 3
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/Case-Sensitive.c -l 3
+# CHECK: 0 locations.
+
+breakpoint set -f case-sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f case-sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
+
+breakpoint set -f %p/Inputs/case-sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f {{.*}}/Inputs/case-sensitive.c -p REGEX-THIS
+# CHECK: At least one location.
+
+breakpoint set -f %p/INPUTS/case-sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/case-sensitive.c -p REGEX-THIS
+# CHECK: 0 locations.
+
+breakpoint set -f Case-Sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f Case-Sensitive.c -p REGEX-THIS
+# CHECK: 0 locations.
+
+breakpoint set -f %p/INPUTS/Case-Sensitive.c -p REGEX-THIS
+# CHECK-LABEL: breakpoint set -f {{.*}}/INPUTS/Case-Sensitive.c -p REGEX-THIS
+# CHECK: 0 locations.
+
+
--- /dev/null
+config.suffixes = ['.test']
else:
config.available_features.add('linux')
-if platform.system() in ['Windows']:
- config.available_features.add('windows')
+config.available_features.add(
+ binary_feature(platform.system() in ['Windows'], 'windows', 'no'))
if re.match(r'^arm(hf.*-linux)|(.*-linux-gnuabihf)', config.target_triple):
config.available_features.add("armhf-linux")
+++ /dev/null
-LEVEL = ../../../make
-
-C_SOURCES := main.c
-CFLAGS_EXTRAS += -std=c99
-
-include $(LEVEL)/Makefile.rules
+++ /dev/null
-"""
-Test case sensitivity of paths on Windows / POSIX
-llvm.org/pr22667
-"""
-
-import os
-import lldb
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test.decorators import *
-from lldbsuite.test import lldbplatform, lldbplatformutil
-
-
-class BreakpointCaseSensitivityTestCase(TestBase):
- mydir = TestBase.compute_mydir(__file__)
- BREAKPOINT_TEXT = 'Set a breakpoint here'
-
- def setUp(self):
- # Call super's setUp().
- TestBase.setUp(self)
- self.line = line_number('main.c', self.BREAKPOINT_TEXT)
-
- @skipIf(hostoslist=no_match(['windows'])) # Skip for non-windows platforms
- def test_breakpoint_matches_file_with_different_case(self):
- """Set breakpoint on file, should match files with different case on Windows"""
- self.build()
- self.case_sensitivity_breakpoint(True)
-
- @skipIf(hostoslist=['windows']) # Skip for windows platforms
- def test_breakpoint_doesnt_match_file_with_different_case(self):
- """Set breakpoint on file, shouldn't match files with different case on POSIX systems"""
- self.build()
- self.case_sensitivity_breakpoint(False)
-
- def case_sensitivity_breakpoint(self, case_insensitive):
- """Set breakpoint on file, should match files with different case if case_insensitive is True"""
-
- # use different case to check CreateTarget
- exe = 'a.out'
- if case_insensitive:
- exe = exe.upper()
-
- exe = self.getBuildArtifact(exe)
-
- # Create a target by the debugger.
- self.target = self.dbg.CreateTarget(exe)
- self.assertTrue(self.target, VALID_TARGET)
- srcdir = self.getSourceDir()
-
- # try both BreakpointCreateByLocation and BreakpointCreateBySourceRegex
- for regex in [False, True]:
- # should always hit
- self.check_breakpoint('main.c', regex, True)
- # should always hit
- self.check_breakpoint(os.path.join(srcdir, 'main.c'), regex, True)
- # different case for directory
- self.check_breakpoint(os.path.join(srcdir.upper(), 'main.c'),
- regex,
- case_insensitive)
- # different case for file
- self.check_breakpoint('Main.c',
- regex,
- case_insensitive)
- # different case for both
- self.check_breakpoint(os.path.join(srcdir.upper(), 'Main.c'),
- regex,
- case_insensitive)
-
- def check_breakpoint(self, file, source_regex, should_hit):
- """
- Check breakpoint hit at given file set by given method
-
- file:
- File where insert the breakpoint
-
- source_regex:
- True for testing using BreakpointCreateBySourceRegex,
- False for BreakpointCreateByLocation
-
- should_hit:
- True if the breakpoint should hit, False otherwise
- """
-
- desc = ' file %s set by %s' % (
- file, 'regex' if source_regex else 'location')
- if source_regex:
- breakpoint = self.target.BreakpointCreateBySourceRegex(
- self.BREAKPOINT_TEXT, lldb.SBFileSpec(file))
- else:
- breakpoint = self.target.BreakpointCreateByLocation(
- file, self.line)
-
- self.assertEqual(breakpoint and breakpoint.GetNumLocations() == 1,
- should_hit,
- VALID_BREAKPOINT + desc)
-
- # Get the breakpoint location from breakpoint after we verified that,
- # indeed, it has one location.
- location = breakpoint.GetLocationAtIndex(0)
-
- self.assertEqual(location.IsValid(),
- should_hit,
- VALID_BREAKPOINT_LOCATION + desc)
-
- process = self.target.LaunchSimple(
- None, None, self.get_process_working_directory())
- self.assertTrue(process, PROCESS_IS_VALID + desc)
-
- if should_hit:
- # Did we hit our breakpoint?
- from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
- threads = get_threads_stopped_at_breakpoint(process, breakpoint)
- self.assertEqual(
- len(threads),
- 1,
- "There should be a thread stopped at breakpoint" +
- desc)
- # The hit count for the breakpoint should be 1.
- self.assertEqual(breakpoint.GetHitCount(), 1)
-
- else:
- # check the breakpoint was not hit
- self.assertEqual(lldb.eStateExited, process.GetState())
- self.assertEqual(breakpoint.GetHitCount(), 0)
-
- # let process finish
- process.Continue()
-
- # cleanup
- self.target.BreakpointDelete(breakpoint.GetID())
+++ /dev/null
-#include <stdio.h>
-
-int
-main()
-{
- printf("Set a breakpoint here.\n");
- return 0;
-}
#include "SystemInitializerTest.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Utility/DataExtractor.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include <thread>
using namespace llvm;
namespace opts {
+static cl::SubCommand BreakpointSubcommand("breakpoints",
+ "Test breakpoint resolution");
cl::SubCommand ModuleSubcommand("module-sections",
"Display LLDB Module Information");
cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
+namespace breakpoint {
+static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
+ cl::Required, cl::sub(BreakpointSubcommand));
+static cl::opt<std::string> CommandFile(cl::Positional,
+ cl::desc("<command-file>"),
+ cl::init("-"),
+ cl::sub(BreakpointSubcommand));
+static cl::opt<bool> Persistent(
+ "persistent",
+ cl::desc("Don't automatically remove all breakpoints before each command"),
+ cl::sub(BreakpointSubcommand));
+
+static llvm::StringRef plural(uintmax_t value) { return value == 1 ? "" : "s"; }
+static void dumpState(const BreakpointList &List, LinePrinter &P);
+static std::string substitute(StringRef Cmd);
+static void evaluateBreakpoints(Debugger &Dbg);
+} // namespace breakpoint
+
namespace module {
cl::opt<bool> SectionContents("contents",
cl::desc("Dump each section's contents"),
static llvm::ManagedStatic<SystemLifetimeManager> DebuggerLifetime;
+void opts::breakpoint::dumpState(const BreakpointList &List, LinePrinter &P) {
+ P.formatLine("{0} breakpoint{1}", List.GetSize(), plural(List.GetSize()));
+ if (List.GetSize() > 0)
+ P.formatLine("At least one breakpoint.");
+ for (size_t i = 0, e = List.GetSize(); i < e; ++i) {
+ BreakpointSP BP = List.GetBreakpointAtIndex(i);
+ P.formatLine("Breakpoint ID {0}:", BP->GetID());
+ AutoIndent Indent(P, 2);
+ P.formatLine("{0} location{1}.", BP->GetNumLocations(),
+ plural(BP->GetNumLocations()));
+ if (BP->GetNumLocations() > 0)
+ P.formatLine("At least one location.");
+ P.formatLine("{0} resolved location{1}.", BP->GetNumResolvedLocations(),
+ plural(BP->GetNumResolvedLocations()));
+ if (BP->GetNumResolvedLocations() > 0)
+ P.formatLine("At least one resolved location.");
+ for (size_t l = 0, le = BP->GetNumLocations(); l < le; ++l) {
+ BreakpointLocationSP Loc = BP->GetLocationAtIndex(l);
+ P.formatLine("Location ID {0}:", Loc->GetID());
+ AutoIndent Indent(P, 2);
+ P.formatLine("Enabled: {0}", Loc->IsEnabled());
+ P.formatLine("Resolved: {0}", Loc->IsResolved());
+ P.formatLine("Address: {0}+{1:x}",
+ Loc->GetAddress().GetSection()->GetName(),
+ Loc->GetAddress().GetOffset());
+ }
+ }
+ P.NewLine();
+}
+
+std::string opts::breakpoint::substitute(StringRef Cmd) {
+ std::string Result;
+ raw_string_ostream OS(Result);
+ while (!Cmd.empty()) {
+ switch (Cmd[0]) {
+ case '%':
+ if (Cmd.consume_front("%p") && (Cmd.empty() || !isalnum(Cmd[0]))) {
+ OS << sys::path::parent_path(CommandFile);
+ break;
+ }
+ // fall through
+ default:
+ size_t pos = Cmd.find('%');
+ OS << Cmd.substr(0, pos);
+ Cmd = Cmd.substr(pos);
+ break;
+ }
+ }
+ return std::move(OS.str());
+}
+
+void opts::breakpoint::evaluateBreakpoints(Debugger &Dbg) {
+ TargetSP Target;
+ Status ST =
+ Dbg.GetTargetList().CreateTarget(Dbg, breakpoint::Target, /*triple*/ "",
+ /*get_dependent_modules*/ false,
+ /*platform_options*/ nullptr, Target);
+ if (ST.Fail()) {
+ errs() << formatv("Failed to create target '{0}: {1}\n", breakpoint::Target,
+ ST);
+ exit(1);
+ }
+
+ auto MB = MemoryBuffer::getFileOrSTDIN(CommandFile);
+ if (!MB) {
+ errs() << formatv("Could not open file '{0}: {1}\n", CommandFile,
+ MB.getError().message());
+ exit(1);
+ }
+
+ LinePrinter P(4, outs());
+ StringRef Rest = (*MB)->getBuffer();
+ while (!Rest.empty()) {
+ StringRef Line;
+ std::tie(Line, Rest) = Rest.split('\n');
+ Line = Line.ltrim();
+ if (Line.empty() || Line[0] == '#')
+ continue;
+
+ if (!Persistent)
+ Target->RemoveAllBreakpoints(/*internal_also*/ true);
+
+ std::string Command = substitute(Line);
+ P.formatLine("Command: {0}", Command);
+ CommandReturnObject Result;
+ if (!Dbg.GetCommandInterpreter().HandleCommand(
+ Command.c_str(), /*add_to_history*/ eLazyBoolNo, Result)) {
+ P.formatLine("Failed: {0}", Result.GetErrorData());
+ continue;
+ }
+
+ dumpState(Target->GetBreakpointList(/*internal*/ false), P);
+ }
+}
+
static void dumpSymbols(Debugger &Dbg) {
for (const auto &File : opts::symbols::InputFilenames) {
ModuleSpec Spec{FileSpec(File, false)};
auto Dbg = lldb_private::Debugger::CreateInstance();
+ if (opts::BreakpointSubcommand)
+ opts::breakpoint::evaluateBreakpoints(*Dbg);
if (opts::ModuleSubcommand)
dumpModules(*Dbg);
else if (opts::SymbolsSubcommand)