-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[debug] Add manticore::debug #123
Conversation
It's not the overhead, but rather being able to compile out the log format messages altogether; it is useful for us to be able to say "if you flip this flag, formatting is redacted at the linker level". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! Now, the question is... do you want to attempt to migrate the entire crate over to manticore::Result
? Unfortunately I think that needs to be done in one shot. =/
We can merge this and do it in a separate CL, or you can give it a shot in this one. I suspect the way you'll wind up doing this is:
- Replace
Result
withcrate::Result
throughout. - Add
fail
,check
andcast
where necessary until the crate compiles again.
If you can think of a way to do this gradually that would be even more awesome, because then you won't be rebasing over everyone else and I can help you get it done faster.
e1ecb2b
to
9be6008
Compare
/// impl. We work around this by calling this macro for every Manticore | ||
/// error definition that has `From` impls. | ||
macro_rules! debug_from { | ||
($e:ident<$trait:ident: $bound:path> => $($f:ty),+ $(,)?) => {$( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This first macro rule is an ugly hack so that this macro can be used with Error<Header>
in src/server/handler.rs. See usage. It works... but I'm not too proud of it. I'm super new to Rust macros, but based on what I've read, there's not really a clean way of doing this besides resorting to proc macros, which seems like a rabbit hole not worth tackling yet. That said, feedback would be appreciated if you think otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really. One option to cut down on repetition is to define something like
macro_rules! debug_from {
(@actual $e:ident[$($tparams:tt)*] => ...) => {
// Use `$($tparams)* as appropriate in <>
};
($e:ident => ...) => {debug_from!(@actual $e[] => ...)};
}
Note that wherever a <>
is allowed, you can leave it empty, e.g. i32<>
is valid Rust. You can use this to your advantage here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I bashed my head against this a bit, but I'm struggling to get any sort of recursive calls to work as I'd expect. For now, I combined two of the macro arms by matching on the tt
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sg. We can bash on it more later.
9be6008
to
682b359
Compare
Hey @mcy, while looking into using the new The approach is to add a few more Let me know what you think. I've moved this PR back to draft status until I fix all the compiler errors. |
I pushed another commit that fixes most of the compiler errors. I highly recommend viewing the individual commits. Assuming this approach is acceptable, the next steps I'm envisioning are: To do in this PR
Future PR(s)
|
The `debug` module is intended to hold debugging helpers, to make debugging Manticore tests easier. This will include: - Redactable logging. - Error creation capture (e.g., capturing where `Err` variants are created). The generated logs can be captured by tests, and eventually get returned through Cerberus's "debug log" functionality. Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
This type cannot be created except via special macros in the `debug` module that generate log statements. We may eventually also attach extra debugging information to errors, and this type is a good place to do so. Signed-off-by: Miguel Young de la Sota <mcyoung@google.com> Fix some syntax and rebase errors Signed-off-by: Kesavan Yogeswaran <hikes@google.com>
9f5eb23
to
254f201
Compare
After rebasing, I noticed that #148 added a new Error in protocol/spdm/error.rs that has a lifetime parameter to refer to some extra error data. I have to think a bit more on how to handle this. |
Some updates:
|
3b80c21
to
781b2c3
Compare
@mcy this is now ready for review and potential merge. I've held off on squashing in case it helps review, but I'll make sure to squash all the commits prefixed with "SQUASHME." I recommend reading my stream of thoughts above for full context. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work. There's a few changes I might suggest but I think those would be better left as follow-ups.
/// impl. We work around this by calling this macro for every Manticore | ||
/// error definition that has `From` impls. | ||
macro_rules! debug_from { | ||
($e:ident<$trait:ident: $bound:path> => $($f:ty),+ $(,)?) => {$( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really. One option to cut down on repetition is to define something like
macro_rules! debug_from {
(@actual $e:ident[$($tparams:tt)*] => ...) => {
// Use `$($tparams)* as appropriate in <>
};
($e:ident => ...) => {debug_from!(@actual $e[] => ...)};
}
Note that wherever a <>
is allowed, you can leave it empty, e.g. i32<>
is valid Rust. You can use this to your advantage here.
@@ -204,7 +207,7 @@ impl<'arena, A: Arena + ?Sized> ArenaExt<'arena> for &'arena A { | |||
/// arena.reset(); | |||
/// let buf3 = arena.alloc_slice::<u8>(64)?; | |||
/// assert_eq!(buf3.len(), 64); | |||
/// # Ok::<(), OutOfMemory>(()) | |||
/// # Ok::<(), manticore::Error<OutOfMemory>>(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I actually don't think this is a very useful error: getting an error location from a failed allocation will point inside of arena code, when it would be much more useful for the caller to see the arena call that emitted the error. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A follow-on task I'm envisioning (and that you incepted me with a few months ago 😄) is to steal ideas from rust-lang/rust#87401: investigate whether we can use #[track_caller]
to automatically track the locations of error conversions performed via ?
. That'd give extra, more useful debug information and would save the need to add fail!
calls in many places.
So my thinking is:
- Use the
Error
type with theArena
trait i.e. no change to current PR state. - If the debug information printed is not useful, callers can still manually add debug info. This is actually already done in some places in src/io/read.rs:
Since adding the fallible
let out = arena .alloc_raw(layout) .map_err(|_| fail!(io::Error::BufferExhausted))?;
Arena
trait calls are only made Since theArena
trait - Add error conversion tracking using
#[track_caller]
if possible. If it isn't, rely on step 2.
FWIW switching the Arena
trait to using core::result::Result
would be pretty easy and I can do that if you do feel strongly that seeing where in arena.rs the error originated would never be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel strongly, if you plan on doing stuff with track_caller.
* Replace usage of `Result` with `crate::Result` nearly everywhere. The individual certificate parsers use the old `Result` type to avoid conflicts with the types returned by the `untrusted` crate, which is used for parsing. * Add some extra `From` implementations to the `debug_from!` macro to allow existing usage with the try operator `?`. Signed-off-by: Kesavan Yogeswaran <hikes@google.com>
fde8306
to
be80b1a
Compare
I've squashed my commits together and this should be good to go now |
/// impl. We work around this by calling this macro for every Manticore | ||
/// error definition that has `From` impls. | ||
macro_rules! debug_from { | ||
($e:ident<$trait:ident: $bound:path> => $($f:ty),+ $(,)?) => {$( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sg. We can bash on it more later.
Started with PR #108 and made some non-structural changes to get it working:
trace!
tofail!
to avoid naming conflict withlog::trace
.A couple of things I wasn't totally sure about:
info!
,error!
, etc.) over the baselog
crate is that the log crate still has some overhead ("an integer load, comparison and jump") even if no logger is set up?Result
type might not be able to be done gradually. Any particular reason why that would be?