m4rw3r/chomp

Debug mode (feature) including backtraces in errors

m4rw3r opened this issue · 3 comments

Problem

Currently it can be a bit hard to debug parsers to see why they do not match the provided input. The fact that Chomp enables the easy splitting into functions, as well as ParseResult::inspect helps a bit, but being forced to add println! statements all over to find the exact part where the parser fails is annoying.

Proposed solution

Add another feature flag for errors which will use an error type which will retrieve a backtrace whenever instantiated. This will provide vaulable information to the user of the parser as he/she can immediately see which part of code the error comes from.

A solution close to what the crate stacktrace does might be suitable. Unsure if so much allocated data is actually necessary for each error (see FrameInfo), since it might be possible to extract and instantiate the relevant function-names and filenames when the trace is actually read.

This still requires a different error type, but I do not think that the combinators need changes for this since the full stack-trace will include any combinator (ie. combinators will just propagate the actual error which already contains the stack-trace from where a condition failed).

The main issue is the use of the Error type defined in chomp::parsers since this type would contain the stack trace. Since it is a public enum it will be somewhat problematic to incorporate any stack-trace without forcing the stack-trace on the library-user which would make the feature incompatible to normal Chomp code (ie. turn on stack-traces, suddenly your code breaks on all the match-blocks using the chomp::parsers::Error type).

Technically the basic Error is straightforward, I am unsure how much matching is actually required on it. If it could be made to be an opaque container for an error with a method to check if there was a specific expected character or not (ie. what now corresponds to matching on Error itself) then the stack-trace could easily be incorporated if the feature-flag is on without breaking user code. This would require #15 to be solved first (or at the same time) so that the Error::String variant will not be necessary or can be merged into the opaque type.

Should probably use the #[cfg(debug)] flag to always enable backtraces in debug-mode and never enable backtraces in release unless a specific feature flag is set. Debug-printing the Error type should show the backtrace if it is either a debug build or the feature flag is set. Programmatically obtaining the backtrace should only be possible with the feature-flag enabled.

Will have to be the debug_assertions flag since debug is not actually set.

Would probably be interesting to put into a separate crate since it is a stack-trace which has zero cost in release-mode but is present in debug and test builds. Other stack-trace crates always allocate at least some space for the stack-trace no matter what.