ReadAnchor throws exception on second run
asctime opened this issue · 6 comments
Is there an existing issue for this?
- I have searched the existing issues
Current behaviour
std::vector<CAddress> ReadAnchors(const fs::path& anchors_db_path)
{
std::vector<CAddress> anchors;
try {
DeserializeFileDB(anchors_db_path, CAddress::V2_DISK(anchors));
LogPrintf("Loaded %i addresses from %s\n", anchors.size(), fs::quoted(fs::PathToString(anchors_db_path.filename())));
} catch (const std::exception&) {
anchors.clear();
}
fs::remove(anchors_db_path);
return anchors;
}
On second run I would get:
EXCEPTION: NSt10filesystem7__cxx1116filesystem_errorE
filesystem error: cannot remove: No such file or directory [... \AppData\Roaming\Bitcoin\anchors.dat]
..\bitcoin-qt.exe in Runaway exception
Attempting blind delete on already-deleted file..
Expected behaviour
No crash on second run, this works for me:
std::vector<CAddress> ReadAnchors(const fs::path& anchors_db_path)
{
std::vector<CAddress> anchors;
try {
DeserializeFileDB(anchors_db_path, CAddress::V2_DISK(anchors));
LogPrintf("Loaded %i addresses from %s\n", anchors.size(), fs::quoted(fs::PathToString(anchors_db_path.filename())));
} catch (const std::exception&) {
anchors.clear();
}
if (fs::exists(anchors_db_path)) {
try {
fs::remove(anchors_db_path);
} catch (const std::filesystem::filesystem_error& e) {
LogPrintf("Error. %s could not be deleted: %s\n", fs::quoted(fs::PathToString(anchors_db_path.filename())), e.what());
}
}
return anchors;
}
I emphasize that I am not very familiar with the code base, and there could be reasons for the way this is done. Just trying to better understand it really..
Steps to reproduce
Compile from source MinGW64, run twice..
Relevant log output
No response
How did you obtain Bitcoin Core
Compiled from source
What version of Bitcoin Core are you using?
26.1
Operating system and version
Windows, MinGW64 (using portable_endian.h)
Machine specifications
No response
Compile from source MinGW64, run twice..
What are the exact steps to reproduce, including the exact operating system version?
Does it happen with the compiled release version as well?
Windows 10. I run the official binary on Linux and that's fine. Different compilers seem to manage the exception slightly differently? Regardless I'm not sure that a blind delete is the right way to do this, is all. Fixed on my side, I just wanted to point it out.
Different compilers seem to manage the exception slightly differently?
That should not be the case. The point of standard C++ library std::filesystem::remove
is to provide the same interface behavior, regardless of compiler or operating system.
The specification says that false
should be returned when the file does not exist, not an exception be thrown.
However, without exact steps to reproduce, using your compiler version, there is little that can be done here.
Regardless I'm not sure that a blind delete is the right way to do this, is all.
Right, it could make sense to catch the exception for other reasons, or not allow it to be thrown, but that is a different question.
According to #29930 (comment) the reason could be that you are using an experimental C++17 standard library, which has bugs?
That should not be the case. The point of standard C++ library
std::filesystem::remove
is to provide the same interface behavior, regardless of compiler or operating system.The specification says that
false
should be returned when the file does not exist, not an exception be thrown.
Ah good point ><. I'll try it once with my clang install, it's a fair bit newer than my gcc which is due to be updated anyway. Ok to close from my side. Thanks.
Closing for now, but please leave a comment if there are more details to debug this issue.