Support MacOS lldb (#7697)
This commit is contained in:
parent
fe4adfe273
commit
ee793669c5
|
|
@ -101,9 +101,15 @@ if (defined $ENV{VERILATOR_ROOT}) {
|
|||
$ENV{VERILATOR_ROOT} = $verilator_root;
|
||||
}
|
||||
|
||||
if ($opt_gdbbt && !gdb_works()) {
|
||||
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
|
||||
$opt_gdbbt = 0;
|
||||
my $lldb_selected = 0;
|
||||
if (($opt_gdb || $opt_gdbbt) && !gdb_works()) {
|
||||
if (lldb_works()) {
|
||||
$lldb_selected = 1;
|
||||
} else {
|
||||
warn "-Info: --gdb or --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
|
||||
$opt_gdbbt = 0;
|
||||
$opt_gdb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Determine runtime flags and run
|
||||
|
|
@ -113,22 +119,35 @@ if ($opt_gdbbt && !gdb_works()) {
|
|||
# then see exactly the contents of @Opt_Verilator_Sw.
|
||||
my @quoted_sw = map { sh_escape($_) } @Opt_Verilator_Sw;
|
||||
if ($opt_gdb) {
|
||||
# Generic GDB interactive
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr(0)
|
||||
. ($ENV{VERILATOR_GDB} || "gdb")
|
||||
. " " . verilator_bin()
|
||||
# Note, uncomment to set breakpoints before running:
|
||||
# ." -ex 'break main'"
|
||||
|
||||
# Note, we must use double-quotes ("run <switches>")
|
||||
# and not single ('run <switches>') below. Bash swallows
|
||||
# escapes as you would expect in a double-quoted string.
|
||||
# That's not true for a single-quoted string, where \'
|
||||
# actually terminates the string -- not what we want!
|
||||
. " -ex \"run " . join(' ', @quoted_sw) . "\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt'");
|
||||
# Note, we must use double-quotes ("run <switches>")
|
||||
# and not single ('run <switches>') below. Bash swallows
|
||||
# escapes as you would expect in a double-quoted string.
|
||||
# That's not true for a single-quoted string, where \'
|
||||
# actually terminates the string -- not what we want!
|
||||
if ($lldb_selected) {
|
||||
# Generic lldb interactive
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr(0)
|
||||
. ($ENV{VERILATOR_GDB} || "lldb")
|
||||
. " " . verilator_bin()
|
||||
# Note, uncomment to set breakpoints before running:
|
||||
# . " -o 'b main'"
|
||||
. " -o 'b exit'" # Need break to keep process active for bt
|
||||
. " -o \"run " . join(' ', @quoted_sw) . "\""
|
||||
. " -o 'settings set term-width 1024'"
|
||||
. " -o 'bt'");
|
||||
} else {
|
||||
# Generic GDB interactive
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr(0)
|
||||
. ($ENV{VERILATOR_GDB} || "gdb")
|
||||
. " " . verilator_bin()
|
||||
# Note, uncomment to set breakpoints before running:
|
||||
# . " -ex 'break main'"
|
||||
. " -ex \"run " . join(' ', @quoted_sw) . "\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt'");
|
||||
}
|
||||
} elsif ($opt_rr) {
|
||||
# Record with rr
|
||||
run (ulimit_stack_unlimited()
|
||||
|
|
@ -136,15 +155,27 @@ if ($opt_gdb) {
|
|||
. "rr record " . verilator_bin()
|
||||
. " " . join(' ', @quoted_sw));
|
||||
} elsif ($opt_gdbbt && $Debug) {
|
||||
# Run under GDB to get gdbbt
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr(0)
|
||||
. "gdb"
|
||||
. " " . verilator_bin()
|
||||
. " --batch --quiet --return-child-result"
|
||||
. " -ex \"run " . join(' ', @quoted_sw)."\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt' -ex 'quit'");
|
||||
# Run under debugger to get gdbbt
|
||||
if ($lldb_selected) {
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr(0)
|
||||
. ($ENV{VERILATOR_GDB} || "lldb")
|
||||
. " " . verilator_bin()
|
||||
. " -o 'b exit'" # Need break to keep process active for bt
|
||||
. " --batch --source-quietly"
|
||||
. " -o \"run " . join(' ', @quoted_sw)."\""
|
||||
. " -o 'settings set term-width 1024'"
|
||||
. " -o 'bt' -o 'quit'");
|
||||
} else {
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr(0)
|
||||
. ($ENV{VERILATOR_GDB} || "gdb")
|
||||
. " " . verilator_bin()
|
||||
. " --batch --quiet --return-child-result"
|
||||
. " -ex \"run " . join(' ', @quoted_sw)."\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt' -ex 'quit'");
|
||||
}
|
||||
} elsif ($opt_valgrind) {
|
||||
# Run under valgrind
|
||||
my $valgrind_bin = ($ENV{VERILATOR_VALGRIND} || "valgrind --error-exitcode=1 --max-stackframe=2815880"
|
||||
|
|
@ -210,6 +241,18 @@ sub gdb_works {
|
|||
return $status == 0;
|
||||
}
|
||||
|
||||
sub lldb_works {
|
||||
$! = undef; # Cleanup -x
|
||||
# macOS system integrity stops attach to system binaries like /bin/sh
|
||||
system("lldb --version"
|
||||
. " --batch --source-quietly"
|
||||
. " -o 'settings set term-width 1024'"
|
||||
. " -o 'bt'"
|
||||
. " -o 'quit'");
|
||||
my $status = $?;
|
||||
return $status == 0;
|
||||
}
|
||||
|
||||
sub aslr {
|
||||
my $want_on = shift;
|
||||
$want_on = $opt_aslr if defined $opt_aslr;
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ class Capabilities:
|
|||
_cached_have_dev_asan = None
|
||||
_cached_have_dev_gcov = None
|
||||
_cached_have_gdb = None
|
||||
_cached_have_lldb = None
|
||||
_cached_have_sc = None
|
||||
_cached_have_solver = None
|
||||
_cached_make_version = None
|
||||
|
|
@ -196,6 +197,13 @@ class Capabilities:
|
|||
Capabilities._cached_have_gdb = bool('Copyright' in out)
|
||||
return Capabilities._cached_have_gdb
|
||||
|
||||
@staticproperty
|
||||
def have_lldb() -> bool: # pylint: disable=no-method-argument
|
||||
if Capabilities._cached_have_lldb is None:
|
||||
out = VtOs.run_capture('lldb --help 2>/dev/null', check=False)
|
||||
Capabilities._cached_have_lldb = bool('USAGE: lldb' in out)
|
||||
return Capabilities._cached_have_lldb
|
||||
|
||||
@staticproperty
|
||||
def have_sc() -> bool: # pylint: disable=no-method-argument
|
||||
if Capabilities._cached_have_sc is None:
|
||||
|
|
@ -237,6 +245,7 @@ class Capabilities:
|
|||
_ignore = Capabilities.have_dev_asan
|
||||
_ignore = Capabilities.have_dev_gcov
|
||||
_ignore = Capabilities.have_gdb
|
||||
_ignore = Capabilities.have_lldb
|
||||
_ignore = Capabilities.have_sc
|
||||
_ignore = Capabilities.have_solver
|
||||
|
||||
|
|
@ -1541,8 +1550,9 @@ class VlTest:
|
|||
debugger_exec_cmd_start = ""
|
||||
debugger_exec_cmd_end = ""
|
||||
if Args.gdbsim:
|
||||
debugger = VtOs.getenv_def('VERILATOR_GDB', "gdb") + " "
|
||||
debugger_exec_cmd_start = " -ex 'run "
|
||||
use_lldb = not self.have_gdb and self.have_lldb
|
||||
debugger = VtOs.getenv_def('VERILATOR_GDB', "lldb" if use_lldb else "gdb") + " "
|
||||
debugger_exec_cmd_start = " -b -o 'run " if use_lldb else " -ex 'run "
|
||||
debugger_exec_cmd_end = "'"
|
||||
cmd = [
|
||||
run_env + debugger + 'vvp', debugger_exec_cmd_start,
|
||||
|
|
@ -1649,14 +1659,20 @@ class VlTest:
|
|||
if not param['executable']:
|
||||
param['executable'] = self.obj_dir + "/" + param['vm_prefix']
|
||||
debugger = ""
|
||||
run_flags = ""
|
||||
trailer = ""
|
||||
if Args.gdbsim:
|
||||
debugger = VtOs.getenv_def('VERILATOR_GDB', "gdb") + " "
|
||||
use_lldb = not self.have_gdb and self.have_lldb
|
||||
debugger = VtOs.getenv_def('VERILATOR_GDB', "lldb" if use_lldb else "gdb") + " "
|
||||
run_flag = " -o " if use_lldb else " -ex "
|
||||
run_flags = run_flag + "'run "
|
||||
trailer = "'"
|
||||
elif Args.rrsim:
|
||||
debugger = "rr record "
|
||||
cmd = [
|
||||
(run_env + debugger + param['executable'] + (" -ex 'run " if Args.gdbsim else "")),
|
||||
(run_env + debugger + param['executable'] + run_flags),
|
||||
*param['all_run_flags'],
|
||||
("'" if Args.gdbsim else ""),
|
||||
trailer
|
||||
]
|
||||
cmd += self.driver_verilated_flags
|
||||
self.run(
|
||||
|
|
@ -1772,6 +1788,10 @@ class VlTest:
|
|||
def have_coroutines(self) -> bool:
|
||||
return Capabilities.have_coroutines
|
||||
|
||||
@property
|
||||
def have_dbg(self) -> bool:
|
||||
return Capabilities.have_gdb or Capabilities.have_lldb
|
||||
|
||||
@property
|
||||
def have_dev_asan(self) -> bool:
|
||||
return Capabilities.have_dev_asan
|
||||
|
|
@ -1784,6 +1804,10 @@ class VlTest:
|
|||
def have_gdb(self) -> bool:
|
||||
return Capabilities.have_gdb
|
||||
|
||||
@property
|
||||
def have_lldb(self) -> bool:
|
||||
return Capabilities.have_lldb
|
||||
|
||||
@property
|
||||
def have_sc(self) -> bool:
|
||||
return Capabilities.have_sc
|
||||
|
|
@ -2899,10 +2923,6 @@ def run_them() -> None:
|
|||
if __name__ == '__main__':
|
||||
os.environ['PYTHONUNBUFFERED'] = "1"
|
||||
|
||||
# GDB is broken on macOS
|
||||
if platform.system() == "Darwin":
|
||||
os.environ['VERILATOR_TEST_NO_GDB'] = "1"
|
||||
|
||||
if ('VERILATOR_ROOT' not in os.environ) and os.path.isfile('../bin/verilator'):
|
||||
os.environ['VERILATOR_ROOT'] = os.getcwd() + "/.."
|
||||
if 'MAKE' not in os.environ:
|
||||
|
|
|
|||
|
|
@ -11,12 +11,10 @@ import vltest_bootstrap
|
|||
|
||||
test.scenarios('vlt')
|
||||
|
||||
have_gdb = 'VERILATOR_GDB' in os.environ
|
||||
if not have_gdb:
|
||||
if 'VERILATOR_TEST_NO_GDB' in os.environ:
|
||||
test.skip("Skipping due to VERILATOR_TEST_NO_GDB")
|
||||
if not test.have_gdb:
|
||||
test.skip("No gdb installed")
|
||||
if 'VERILATOR_TEST_NO_GDB' in os.environ:
|
||||
test.skip("Skipping due to VERILATOR_TEST_NO_GDB")
|
||||
if not test.have_dbg:
|
||||
test.skip("No debugger installed")
|
||||
|
||||
test.compile()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue