mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Fix compilers seeing empty input due to file system races (#4708).
This commit is contained in:
parent
ed05caec93
commit
b15ef49c57
1
Changes
1
Changes
@ -34,6 +34,7 @@ Verilator 5.019 devel
|
||||
* Fix MingW compilation (#4675). [David Ledger]
|
||||
* Fix trace when using SystemC with certain configurations (#4676). [Anthony Donlon]
|
||||
* Fix C++20 compilation errors (#4670).
|
||||
* Fix compilers seeing empty input due to file system races (#4708). [Flavien Solt]
|
||||
|
||||
|
||||
Verilator 5.018 2023-10-30
|
||||
|
@ -191,7 +191,7 @@ void V3FileDependImp::writeTimes(const string& filename, const string& cmdlineIn
|
||||
// Read stats of files we create after we're done making them
|
||||
// (except for this file, of course)
|
||||
DependFile* const dfp = const_cast<DependFile*>(&(*iter));
|
||||
V3Options::fileNfsFlush(dfp->filename());
|
||||
V3Os::filesystemFlush(dfp->filename());
|
||||
dfp->loadStats();
|
||||
off_t showSize = iter->size();
|
||||
ino_t showIno = iter->ino();
|
||||
@ -256,7 +256,7 @@ bool V3FileDependImp::checkTimes(const string& filename, const string& cmdlineIn
|
||||
*ifp >> quote;
|
||||
const string chkFilename = V3Os::getline(*ifp, '"');
|
||||
|
||||
V3Options::fileNfsFlush(chkFilename);
|
||||
V3Os::filesystemFlush(chkFilename);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
||||
struct stat chkStat;
|
||||
const int err = stat(chkFilename.c_str(), &chkStat);
|
||||
|
@ -456,23 +456,6 @@ bool V3Options::fileStatNormal(const string& filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void V3Options::fileNfsFlush(const string& filename) {
|
||||
// NFS caches stat() calls so to get up-to-date information must
|
||||
// do a open or opendir on the filename.
|
||||
// Faster to just try both rather than check if a file is a dir.
|
||||
#ifdef _MSC_VER
|
||||
if (int fd = ::open(filename.c_str(), O_RDONLY)) { // LCOV_EXCL_BR_LINE
|
||||
if (fd > 0) ::close(fd);
|
||||
}
|
||||
#else
|
||||
if (DIR* const dirp = opendir(filename.c_str())) { // LCOV_EXCL_BR_LINE
|
||||
closedir(dirp); // LCOV_EXCL_LINE
|
||||
} else if (int fd = ::open(filename.c_str(), O_RDONLY)) { // LCOV_EXCL_BR_LINE
|
||||
if (fd > 0) ::close(fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
string V3Options::fileExists(const string& filename) {
|
||||
// Surprisingly, for VCS and other simulators, this process
|
||||
// is quite slow; presumably because of re-reading each directory
|
||||
|
@ -697,7 +697,6 @@ public:
|
||||
void filePathLookedMsg(FileLine* fl, const string& modname);
|
||||
V3LangCode fileLanguage(const string& filename);
|
||||
static bool fileStatNormal(const string& filename);
|
||||
static void fileNfsFlush(const string& filename);
|
||||
|
||||
// METHODS (other OS)
|
||||
static void throwSigsegv();
|
||||
|
28
src/V3Os.cpp
28
src/V3Os.cpp
@ -45,6 +45,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
||||
#define PATH_MAX MAX_PATH
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <utime.h>
|
||||
#endif
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
@ -58,6 +59,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
||||
# include <bcrypt.h> // BCryptGenRandom
|
||||
# include <chrono>
|
||||
# include <direct.h> // mkdir
|
||||
# include <io.h> // open, read, write, close
|
||||
# include <psapi.h> // GetProcessMemoryInfo
|
||||
# include <thread>
|
||||
// These macros taken from gdbsupport/gdb_wait.h in binutils-gdb
|
||||
@ -74,6 +76,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
||||
# include <sys/time.h>
|
||||
# include <sys/wait.h> // Needed on FreeBSD for WIFEXITED
|
||||
# include <unistd.h> // usleep
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
@ -294,6 +297,31 @@ void V3Os::createDir(const string& dirname) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void V3Os::filesystemFlush(const string& dirname) {
|
||||
// NFS caches stat() calls so to get up-to-date information must
|
||||
// do a open or opendir on the filename.
|
||||
#ifdef _MSC_VER
|
||||
if (int fd = ::open(filename.c_str(), O_RDONLY)) { // LCOV_EXCL_BR_LINE
|
||||
if (fd > 0) ::close(fd);
|
||||
}
|
||||
#else
|
||||
{
|
||||
// Linux kernel may not reread from NFS unless timestamp modified
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
const int err = utimes(dirname.c_str(), &tv);
|
||||
// Not an error
|
||||
if (err != 0) UINFO(1, "-Info: File not statable: " << dirname << endl);
|
||||
}
|
||||
// Faster to just try both rather than check if a file is a dir.
|
||||
if (DIR* const dirp = opendir(dirname.c_str())) { // LCOV_EXCL_BR_LINE
|
||||
closedir(dirp); // LCOV_EXCL_LINE
|
||||
} else if (int fd = ::open(dirname.c_str(), O_RDONLY)) { // LCOV_EXCL_BR_LINE
|
||||
if (fd > 0) ::close(fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
|
||||
#ifdef _MSC_VER
|
||||
try {
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
|
||||
// METHODS (directory utilities)
|
||||
static void createDir(const string& dirname);
|
||||
static void filesystemFlush(const string& dirname);
|
||||
static void unlinkRegexp(const string& dir, const string& regexp);
|
||||
|
||||
// METHODS (random)
|
||||
|
@ -636,9 +636,12 @@ static void verilate(const string& argString) {
|
||||
// --FRONTEND------------------
|
||||
|
||||
// Cleanup
|
||||
V3Os::unlinkRegexp(v3Global.opt.hierTopDataDir(), v3Global.opt.prefix() + "_*.tree");
|
||||
// Ideally we'd do prefix + "_*.*", and prefix + ".*", but this seems
|
||||
// potentially disruptive to old behavior
|
||||
V3Os::unlinkRegexp(v3Global.opt.hierTopDataDir(), v3Global.opt.prefix() + "_*.dot");
|
||||
V3Os::unlinkRegexp(v3Global.opt.hierTopDataDir(), v3Global.opt.prefix() + "_*.tree");
|
||||
V3Os::unlinkRegexp(v3Global.opt.hierTopDataDir(), v3Global.opt.prefix() + "_*.txt");
|
||||
V3Os::unlinkRegexp(v3Global.opt.hierTopDataDir(), v3Global.opt.prefix() + "_*_DepSet_*");
|
||||
|
||||
// Internal tests (after option parsing as need debug() setting,
|
||||
// and after removing files as may make debug output)
|
||||
@ -717,6 +720,9 @@ static void verilate(const string& argString) {
|
||||
argString);
|
||||
}
|
||||
|
||||
V3Os::filesystemFlush(v3Global.opt.makeDir());
|
||||
if (v3Global.opt.hierTop()) V3Os::filesystemFlush(v3Global.opt.hierTopDataDir());
|
||||
|
||||
// Final writing shouldn't throw warnings, but...
|
||||
V3Error::abortIfWarnings();
|
||||
}
|
||||
@ -747,6 +753,7 @@ static void execBuildJob() {
|
||||
UINFO(1, "Start Build\n");
|
||||
|
||||
const string cmdStr = buildMakeCmd(v3Global.opt.prefix() + ".mk", "");
|
||||
V3Os::filesystemFlush(v3Global.opt.hierTopDataDir());
|
||||
const int exit_code = V3Os::system(cmdStr);
|
||||
if (exit_code != 0) {
|
||||
v3error(cmdStr << " exited with " << exit_code << std::endl);
|
||||
@ -759,6 +766,7 @@ static void execHierVerilation() {
|
||||
const string makefile = v3Global.opt.prefix() + "_hier.mk ";
|
||||
const string target = v3Global.opt.build() ? " hier_build" : " hier_verilation";
|
||||
const string cmdStr = buildMakeCmd(makefile, target);
|
||||
V3Os::filesystemFlush(v3Global.opt.hierTopDataDir());
|
||||
const int exit_code = V3Os::system(cmdStr);
|
||||
if (exit_code != 0) {
|
||||
v3error(cmdStr << " exited with " << exit_code << std::endl);
|
||||
|
Loading…
Reference in New Issue
Block a user