This centralizes the message translation and also provides a more generic interoperability with other libraries that expect to use std error codes.
Details
Diff Detail
Event Timeline
If you like, you might want to consider the recently introduced llvm::Error
which has more checking to ensure errors aren't accidentally
ignored/dropped.
I like the idea of llvm::Error if only because it permits for more descriptive messages like so:
llvm::make_error<GenericError>("unexpected relocation in CIE")
without having to make a billion error codes.
Convert everything to using llvm::Error.
I chose to do this a little bit different way than what is probably normal. There are two distinct codepaths. The DIA codepath and the native PDB parsing codepaths. I wanted to be able to "namespace" the types of errors that each codepath can produce, so that I could make sure I was not returning a DIA error from the raw codepath, and vice versa.
At the same time, I did not want to make 100 different subclasses of ErrorInfo, but I *did* want error messages to be consistent, so that all corrupt file errors have the same error message, etc.
So I chose a hybrid. I have a DIAError, a RawError, and a GenericError. Each one defines its own set of error code constants that you can (optionally) use when making the error. In all cases you also (optionally) pass a context string that gives more detailed information about the site the error occurred at. This way the class (DIAError, RawError, etc) provides the high level error message banner, the code provides a consistent general description of the error, and the context provides the detail.
A nice advantage of this is that when converting to a std error_code, you already have an error category defines which translates it into a useful error message.
In the future, I have some more ideas here that will make this even better. Instead of using an error code, we can define a class for each custom error condition that takes its own set of constructor arguments and has a format() method. This way we could do something like:
make_error<RawError>(corrupt_file(Path), "No MSF Superblock")
and it could format it as
Native PDB File Error: The PDB file 'c:\foo.pdb' is corrupt. Reason: No MSF Superblock'
and this corrupt_file class would know how to format the parameters intelligently, instead of just slapping the context onto the end of the string as we currently do.
Adding lang on this review since he wrote the Error stuff, and make he can offer some suggestions about if I'm using this correctly.
include/llvm/DebugInfo/PDB/DIA/DIASupport.h | ||
---|---|---|
25–34 ↗ | (On Diff #56323) | why not push_macro and pop_macro around the dia includes? |
lgtm
It would be nice if we could test the error paths here better, but I'd rather not check in distinct corrupt PDBs for every error path. If we ever care about perfect error handling we will need to fuzz this.
lib/DebugInfo/PDB/Raw/DbiStream.cpp | ||
---|---|---|
110 | Maybe write a helper like errorCorruptFile(StringRef) that you can call here in the return? It might save a line break on all these error paths. Up to you. |
Bot is red
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/12582
There is include fix patch, but it still failed test in related code
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/12583
Maybe write a helper like errorCorruptFile(StringRef) that you can call here in the return? It might save a line break on all these error paths. Up to you.