-
Notifications
You must be signed in to change notification settings - Fork 60
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
fix panic_handler #84
Conversation
Did you try compiling without being |
Perhaps instead of modifying the existing macro, we need to add one specific for #[macro_export]
macro_rules! nostd_panic_handler {
() => {
/// A panic handler for `no_std`.
#[cfg(not(test))]
#[no_mangle]
#[panic_handler]
fn custom_panic(info: &core::panic::PanicInfo<'_>) -> ! {
if let Some(location) = info.location() {
$crate::log::sol_log(location.file());
}
// Panic reporting.
$crate::log::sol_log("** PANICKED **");
// Never returns.
loop {}
}
};
} |
yeah that sounds good. |
default_panic_handler
75f4f99
to
4159cb3
Compare
i had a wrong understanding about how panic works in sbf and now it's corrected: std:
no_std:
so when using std, we define |
sdk/pinocchio/src/entrypoint/mod.rs
Outdated
@@ -252,12 +254,24 @@ macro_rules! default_panic_handler { | |||
/// Default panic handler. | |||
#[cfg(all(not(feature = "custom-panic"), target_os = "solana"))] | |||
#[no_mangle] | |||
fn custom_panic(info: &core::panic::PanicInfo<'_>) { | |||
#[panic_handler] |
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.
Let's remove the #[panic_handler]
attribute from here. The default_panic_handler
will be used when you import pinocchio
as a no_std
but your program links against the std
.
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.
so four cases here:
- if program is std, they'll need to manually specify
features = ["std"]
in their Cargo.toml. in that casecustom-panic
(usingmsg
) will be used. - if a program is no_std, rustc compiler will ask them to specify a
[panic_handler]
, which is whathandler
doing. - if a program is no_std but specifying
features = ["std"]
, this should be undefined behavior (e.g.format
in pinocchio won't work anyways) - if a program is std while not specifying
features = ["std"]
, this is kind of shady.
to conclude,
- with this
[panic_handler]
, we discourage the fourth case as std will generate a builtin[panic_handler]
and they will conflict. - without this
[panic_handler]
, people cannot useentrypoint!
. they need to useprogram_entrypoint!
and add a[panic_handler]
themself.
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.
Few comments:
- in the first case, you could still have
pinocchio
as "no_std" even though your program isstd
. That would meanpinocchio
won't use anything from thestd
but your program might. - third case probably will fail compilation, since
std
won't be available. - fourth case is not an ideal scenario, but it could happen quite often. The benefit of having
pinocchio
as a "no_std" is that it won't bring all theformat!
stuff automatically (reduces the binary size), but you might still have a library in your program that requiresstd
.
Let's add a specific opt-in #[macro_export]
macro_rules! nostd_panic_handler {
() => {
/// A panic handler for `no_std`.
#[cfg(not(test))]
#[no_mangle]
#[panic_handler]
fn handler(info: &core::panic::PanicInfo<'_>) -> ! {
if let Some(location) = info.location() {
unsafe {
$crate::syscalls::sol_panic_(
location.file().as_ptr(),
location.file().len() as u64,
location.line() as u64,
location.column() as u64,
)
}
} else {
$crate::log::sol_log("** PANICKED **");
unsafe { $crate::syscalls::abort() }
}
}
};
} |
When your program is program_entrypoint!(...);
no_allocator!();
nostd_panic_handler!(); When your program links against the entrypoint(...); |
the functionality difference between the two is only CU diff and format? can we just deprecate the std |
Soon we can deprecate it. At the moment the one with the In rust 1.84, We will be able to use: if let Some(Some(mm)) = info.message().map(|mes| mes.as_str()) {
let mes = mm.as_bytes();
unsafe {
$crate::syscalls::sol_log_(mes.as_ptr(), mes.len() as u64);
}
} |
@publicqi Wondering if you had a chance to look into my last comment. I am preparing a release and ideally would like to include this fix. |
yes. i'll fix it |
@febo ready for review. updated some docs too so hopefully it's clear enough. |
force pushed to clean the messy commits |
Looks great – just a nit: let's remove the |
good catch. fixed. |
One more thing, I think the changes to the |
ahh yes... |
now should be good. i rebased the wrong |
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.
Looks great – thanks!
This code doesn't compile now. Error message is