diff --git a/bin/verilator b/bin/verilator index e5af6da66..c78b8c2d5 100755 --- a/bin/verilator +++ b/bin/verilator @@ -31,6 +31,7 @@ my $opt_gdb; my $opt_rr; my $opt_gdbbt; my $opt_quiet_exit; +my $opt_unlimited_stack = 1; # No arguments can't do anything useful. Give help if ($#ARGV < 0) { @@ -49,16 +50,17 @@ foreach my $sw (@ARGV) { Getopt::Long::config("no_auto_abbrev", "pass_through"); if (! GetOptions( # Major operating modes - "help" => \&usage, - "debug" => \&debug, - # "version!" => \&version, # Also passthru'ed + "help" => \&usage, + "debug" => \&debug, + # "version!" => \&version, # Also passthru'ed # Switches - "gdb!" => \$opt_gdb, - "gdbbt!" => \$opt_gdbbt, - "quiet-exit!" => \$opt_quiet_exit, - "rr!" => \$opt_rr, + "gdb!" => \$opt_gdb, + "gdbbt!" => \$opt_gdbbt, + "quiet-exit!" => \$opt_quiet_exit, + "rr!" => \$opt_rr, + "unlimited-stack!" => \$opt_unlimited_stack, # Additional parameters - "<>" => sub {}, # Ignored + "<>" => sub {}, # Ignored )) { pod2usage(-exitstatus => 2, -verbose => 0); } @@ -76,7 +78,8 @@ if ($opt_gdbbt && !gdb_works()) { my @quoted_sw = map { sh_escape($_) } @Opt_Verilator_Sw; if ($opt_gdb) { # Generic GDB interactive - run (aslr_off() + run (ulimit_stack_unlimited() + . aslr_off() . ($ENV{VERILATOR_GDB} || "gdb") . " " . verilator_bin() # Note, uncomment to set breakpoints before running: @@ -92,12 +95,14 @@ if ($opt_gdb) { . " -ex 'bt'"); } elsif ($opt_rr) { # Record with rr - run (aslr_off() + run (ulimit_stack_unlimited() + . aslr_off() . "rr record " . verilator_bin() . " " . join(' ', @quoted_sw)); } elsif ($opt_gdbbt && $Debug) { # Run under GDB to get gdbbt - run (aslr_off() + run (ulimit_stack_unlimited() + . aslr_off() . "gdb" . " " . verilator_bin() . " --batch --quiet --return-child-result" @@ -106,10 +111,13 @@ if ($opt_gdb) { . " -ex 'bt' -ex 'quit'"); } elsif ($Debug) { # Debug - run(aslr_off() . verilator_bin() . " " . join(' ', @quoted_sw)); + run(ulimit_stack_unlimited() + . aslr_off() + . verilator_bin() + . " " . join(' ', @quoted_sw)); } else { # Normal, non gdb - run(verilator_bin() . " " . join(' ', @quoted_sw)); + run(ulimit_stack_unlimited() . verilator_bin() . " " . join(' ', @quoted_sw)); } #---------------------------------------------------------------------- @@ -180,6 +188,17 @@ sub aslr_off { } } +sub ulimit_stack_unlimited { + return "" if !$opt_unlimited_stack; + system("ulimit -s unlimited 2>/dev/null"); + my $status = $?; + if ($status == 0) { + return "ulimit -s unlimited 2>/dev/null; exec "; + } else { + return ""; + } +} + sub run { # Run command, check errors my $command = shift; @@ -419,6 +438,7 @@ detailed descriptions of these arguments. --trace-threads Enable FST waveform creation on separate threads --trace-underscore Enable tracing of _signals -U Undefine preprocessor define + --no-unlimited-stack Don't disable stack size limit --unroll-count Tune maximum loop iterations --unroll-stmts Tune maximum loop body size --unused-regexp Tune UNUSED lint signals diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index ffb990356..21be8775f 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1383,6 +1383,11 @@ Summary: Undefines the given preprocessor symbol. +.. option:: --no-unlimited-stack + + Verilator tries to disable stack size limit using + :command:`ulimit -s unlimited` command. This option turns this behavior off. + .. option:: --unroll-count Rarely needed. Specifies the maximum number of loop iterations that may be diff --git a/src/V3Options.cpp b/src/V3Options.cpp index bd1fa208b..64b9d2b60 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1472,6 +1472,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char DECL_OPTION("-U", CbPartialMatch, &V3PreShell::undef); DECL_OPTION("-underline-zero", OnOff, &m_underlineZero); // Deprecated + DECL_OPTION("-no-unlimited-stack", CbCall, []() {}); // Processed only in bin/verilator shell DECL_OPTION("-unroll-count", Set, &m_unrollCount).undocumented(); // Optimization tweak DECL_OPTION("-unroll-stmts", Set, &m_unrollStmts).undocumented(); // Optimization tweak DECL_OPTION("-unused-regexp", Set, &m_unusedRegexp); diff --git a/test_regress/t/t_flag_no_unlimited_stack.pl b/test_regress/t/t_flag_no_unlimited_stack.pl new file mode 100755 index 000000000..ef1a415a2 --- /dev/null +++ b/test_regress/t/t_flag_no_unlimited_stack.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2022 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +# Just check whether the flag is recognized. +lint( + verilator_flags2 => ["--no-unlimited-stack"], + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_no_unlimited_stack.v b/test_regress/t/t_flag_no_unlimited_stack.v new file mode 100644 index 000000000..a56f76564 --- /dev/null +++ b/test_regress/t/t_flag_no_unlimited_stack.v @@ -0,0 +1,8 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2005 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); +endmodule