Update hyperlight-guest-tracing crate to conditionally enable traces at compile time#752
Conversation
1111812 to
de70a4c
Compare
jprendes
left a comment
There was a problem hiding this comment.
Can we make the macro crate take no feature?
That way the max length check would stay in place (and I think they should, otherwise suddenly enabling a feature could mean your code doesn't compile anymore is you had exceeded the length).
Also we would avoid having to recompile the macro crate. But I don't know if that has any real impact.
What I would do, is make create_trace_record as always inline, and make it a no-op if the feature is disabled in the hyperlight_guest_tracing crate
So these are the two options we've got:
I am not sure which one is the best for us, but I tend to agree with you @jprendes, turning on a feature and your code not compiling is not a good overall experience. |
|
@dblnz I don't feel super incredibly strongly either way, but I just feel that it is cleaner to avoid inserting code that will then need to be optimised out, even if we are fairly confident in the optimisations. I also don't quite follow where there is a static check (that could break compilation) being omitted in the non-trace case? I would say that anything that we can check statically, we should unconditionally check in the macro code, basically doing everything the same up to actually putting the tokens in. I do see that there is a dynamic check in the macro-inserted code, but that doesn't affect compilation. I also don't fully understand why that check is dynamic---I think it would be preferable to make it happen at macro-run-time, since it seems to check the length of a literal, and then it would be easy to make it happen unconditionally, even when not actually expanding into code. |
Signed-off-by: Doru Blânzeanu <[email protected]>
- this helps with later conditionally compiling only the tracing code depending on a feature Signed-off-by: Doru Blânzeanu <[email protected]>
The check cannot happen at macro-run-time, because the below static check uses the const _: () = assert!(
#_entry_msg.len() <= hyperlight_guest_tracing::MAX_TRACE_MSG_LEN,
"Trace message exceeds the maximum bytes length",
);I agree that the length check should happen no matter if the tracing is enabled or not, I'll make the change to do that. The compilation time remark that @jprendes mentioned was in reference to having the feature // hyperlight-guest-tracing #[cfg(feature = "trace")]
#[inline(always)]
pub fn create_trace_record(_msg: &str) {
// actual creation of record
}
#[cfg(not(feature = "trace"))]
#[inline(always)]
pub fn create_trace_record(_msg: &str) {}// hyperlight-guest-tracing-macro let expanded = quote! {
{
const _: () = assert!(
#entry_msg.len() <= hyperlight_guest_tracing::MAX_TRACE_MSG_LEN,
"Trace message exceeds the maximum bytes length",
);
::hyperlight_guest_tracing::create_trace_record(#entry_msg);
let __trace_result = #statement;
::hyperlight_guest_tracing::create_trace_record(#exit_msg);
__trace_result
} |
- This allows the use of the 'hyperlight-guest-tracing' without having the tracing enabled - Now the user can select at compile time whether the macros enable tracing or not - Before this change, the crate using the macros from hyperlight-guest-tracing-macro needed to define a features called 'trace_guest' because the generated code would gate everything with that feature - The change makes the generation of code dependent on the 'trace' feature - Some of the variables used in the macros were prefixed with an '_' to avoid warnings when the 'trace' feature is not set Signed-off-by: Doru Blânzeanu <[email protected]>
- This is needed for the tests to pass because the macros use 'hyperlight_guest_tracing::' which cannot be imported by 'hyperlight_guest_tracing_macro' bacause it would create a circular dependency. - The caveat is that when using 'hyperlight_guest_tracing_macro' one needs to have as a dependency 'hyperlight_guest_tracing' also Signed-off-by: Doru Blânzeanu <[email protected]>
Signed-off-by: Doru Blânzeanu <[email protected]>
de70a4c to
130dc40
Compare
It is a const evaluated check, so it happens at compilation time, it's a no-op at runtime. |
jprendes
left a comment
There was a problem hiding this comment.
LGTM.
I have a small preference for the macro not changing behaviour depending on the feature, the opposite of @syntactically, but either option will do the job, so... ship it! :-)
Ah, got it.
Sorry, I missed the binding (was looking for a
Relying too much on cross-module inlining still makes me a tad bit uneasy, but perhaps I have just been burned one time to many by C compilers/accidental dynamic linking/etc. Up to you @dblnz. |
Description
This PR addresses two things
trace!macro empty messagehyperlight-guest-tracing-macroto not generate code gated by#[cfg(feature = "trace_guest")]because that causes errors like below if the user does not define a feature with the exact nametrace_guest.hyperlight-guest-tracingcrate to generate trace records in the guest (outside ofhyperlight-guestandhyperlight-guest-bincrates)Guests compile example
Solution
Define a
tracefeature for thehyperlight-guest-tracingcrate and based on whether it is set or not enable either the tracing implementation or a dummy/empty implementation.This makes removing the
#[cfg(feature = "trace_guest")] fromhyperlight-guest-tracing-macro` unnecessary.