diff --git a/src/V3Error.cpp b/src/V3Error.cpp index 662625feb..300437768 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -97,19 +97,19 @@ void V3ErrorGuarded::vlAbortOrExit() VL_REQUIRES(m_mutex) { std::cerr << msgPrefix() << "Aborting since under --debug" << endl; V3Error::vlAbort(); } -#ifndef V3ERROR_NO_GLOBAL_ - else if (v3Global.opt.verilateJobs() > 1 - && v3Global.mainThreadId() != std::this_thread::get_id()) { - VL_GCOV_DUMP(); // No static destructors are called, thus must be called manually. - // Exit without triggering any global destructors. - // Used to prevent detached V3ThreadPool jobs accessing destroyed static objects. +#ifndef V3ERROR_NO_GLOBAL_ + if (v3Global.opt.verilateJobs() > 1 && v3Global.mainThreadId() != std::this_thread::get_id()) { + // No static destructors are called, thus must be called manually. + VL_GCOV_DUMP(); + // Exit without triggering any global destructors. Used to prevent + // detached V3ThreadPool jobs accessing destroyed static objects. ::_exit(1); } + v3Global.vlExit(1); +#else + std::exit(1); #endif - else { - std::exit(1); - } } string V3ErrorGuarded::warnMoreSpaces() VL_REQUIRES(m_mutex) { @@ -369,6 +369,9 @@ void V3Error::abortIfWarnings() { void V3Error::vlAbort() { VL_GCOV_DUMP(); +#ifndef V3ERROR_NO_GLOBAL_ + v3Global.shutdown(); +#endif std::abort(); } std::ostringstream& V3Error::v3errorPrep(V3ErrorCode code) VL_ACQUIRE(s().m_mutex) { diff --git a/src/V3Error.h b/src/V3Error.h index 008b70900..b945a3926 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -459,12 +459,8 @@ public: // ###################################################################### class V3Error final { - // Base class for any object that wants debugging and error reporting - // CONSTRUCTORS - V3Error() { - std::cerr << ("Static class"); - V3Error::vlAbort(); - } + // Static members only + V3Error() = delete; public: static V3ErrorGuarded& s() VL_MT_SAFE { // Singleton diff --git a/src/V3Global.cpp b/src/V3Global.cpp index a3e208d4d..1c60a2d76 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -24,6 +24,7 @@ #include "V3HierBlock.h" #include "V3LinkCells.h" #include "V3Parse.h" +#include "V3PreShell.h" #include "V3Stats.h" #include "V3ThreadPool.h" @@ -53,11 +54,18 @@ void V3Global::boot() { } void V3Global::shutdown() { + V3PreShell::shutdown(); VL_DO_CLEAR(delete m_hierPlanp, m_hierPlanp = nullptr); // delete nullptr is safe VL_DO_CLEAR(delete m_threadPoolp, m_threadPoolp = nullptr); // delete nullptr is safe #ifdef VL_LEAK_CHECKS if (m_rootp) VL_DO_CLEAR(m_rootp->deleteTree(), m_rootp = nullptr); #endif + FileLine::deleteAllRemaining(); +} + +void V3Global::vlExit(int status) { + shutdown(); + std::exit(status); } void V3Global::checkTree() const { rootp()->checkTree(); } diff --git a/src/V3Global.h b/src/V3Global.h index 157a90eef..3c4e502ff 100644 --- a/src/V3Global.h +++ b/src/V3Global.h @@ -147,6 +147,8 @@ public: void boot(); void shutdown(); // Release allocated resources + void vlExit(int status); + // ACCESSORS (general) AstNetlist* rootp() const VL_MT_SAFE { return m_rootp; } V3ThreadPool* threadPoolp() const VL_PURE { return m_threadPoolp; } diff --git a/src/V3Options.cpp b/src/V3Options.cpp index ccc4b1d03..08e0a8596 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1272,9 +1272,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-debugi-", CbPartialMatchVal, [this](const char* optp, const char* valp) { m_debugLevel[optp] = std::atoi(valp); }); - DECL_OPTION("-debug-abort", CbCall, - V3Error::vlAbort) - .undocumented(); // See also --debug-sigsegv + DECL_OPTION("-debug-abort", CbCall, []() { + V3Error::vlAbort(); + }).undocumented(); // See also --debug-sigseg DECL_OPTION("-debug-check", OnOff, &m_debugCheck); DECL_OPTION("-debug-collision", OnOff, &m_debugCollision).undocumented(); DECL_OPTION("-debug-emitv", OnOff, &m_debugEmitV).undocumented(); @@ -1392,15 +1392,15 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-gdbbt", CbCall, []() {}); // Processed only in bin/verilator shell DECL_OPTION("-generate-key", CbCall, [this]() { cout << protectKeyDefaulted() << endl; - std::exit(0); + v3Global.vlExit(0); }); DECL_OPTION("-getenv", CbVal, [](const char* valp) { cout << V3Options::getenvBuiltins(valp) << endl; - std::exit(0); + v3Global.vlExit(0); }); DECL_OPTION("-get-supported", CbVal, [](const char* valp) { cout << V3Options::getSupported(valp) << endl; - std::exit(0); + v3Global.vlExit(0); }); DECL_OPTION("-hierarchical", OnOff, &m_hierarchical); @@ -1719,7 +1719,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-V", CbCall, [this]() { showVersion(true); - std::exit(0); + v3Global.vlExit(0); }); DECL_OPTION("-v", CbVal, [this, &optdir](const char* valp) { V3Options::addLibraryFile(parseFileArg(optdir, valp), work()); @@ -1739,7 +1739,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, }); DECL_OPTION("-version", CbCall, [this]() { showVersion(false); - std::exit(0); + v3Global.vlExit(0); }); DECL_OPTION("-vpi", OnOff, &m_vpi); diff --git a/src/Verilator.cpp b/src/Verilator.cpp index fbd1648e2..7479b269e 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -147,7 +147,7 @@ static void process() { V3Error::abortIfErrors(); if (v3Global.opt.debugExitParse()) { cout << "--debug-exit-parse: Exiting after parse\n"; - std::exit(0); + v3Global.vlExit(0); } // Convert parseref's to varrefs, and other directly post parsing fixups @@ -173,7 +173,7 @@ static void process() { V3Error::abortIfErrors(); if (v3Global.opt.serializeOnly()) emitXmlOrJson(); cout << "--debug-exit-uvm23: Exiting after UVM-supported pass\n"; - std::exit(0); + v3Global.vlExit(0); } // Remove parameters by cloning modules to de-parameterized versions @@ -204,7 +204,7 @@ static void process() { V3Error::abortIfErrors(); if (v3Global.opt.serializeOnly()) emitXmlOrJson(); cout << "--debug-exit-uvm: Exiting after UVM-supported pass\n"; - std::exit(0); + v3Global.vlExit(0); } // Calculate and check widths, edit tree to TRUNC/EXTRACT any width mismatches @@ -819,7 +819,7 @@ static void execBuildJob() { if (exit_code != 0) { v3error(cmdStr << " exited with " << exit_code << std::endl); - std::exit(exit_code); + v3Global.vlExit(exit_code); } } @@ -832,7 +832,7 @@ static void execHierVerilation() { const int exit_code = V3Os::system(cmdStr); if (exit_code != 0) { v3error(cmdStr << " exited with " << exit_code << std::endl); - std::exit(exit_code); + v3Global.vlExit(exit_code); } } @@ -884,9 +884,7 @@ int main(int argc, char** argv) { V3DiagSarif::output(true); // Explicitly release resources - V3PreShell::shutdown(); v3Global.shutdown(); - FileLine::deleteAllRemaining(); if (!v3Global.opt.quietStats() && !v3Global.opt.preprocOnly()) { V3Stats::addStatPerf(V3Stats::STAT_CPUTIME, cpuTimeTotal.deltaTime());