1

This is more of a "teach me how to fish" that may be useful for others too.

I have written a rather complex Anchor program. When I run the integration test for it, it fails right away with the following program logs:

Program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS invoke [1]
Program log: Instruction: Foo
Program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS consumed 5981 of 1000000 compute units
Program failed to complete: Access violation in stack frame 7 at address 0x200007fd8 of size 8 by instruction #4170
Program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS failed: Program failed to complete

I could blindly keep changing things till it goes away but that's not very productive.

  • Is it possible to narrow down the issue with the info provided in the log message? i.e. address 0x200007fd8 or instruction #4170? How would you go about that?
  • Are there any additional logging that could be enabled to provide more info about this?

For the latter, I note that the Solana documentation also mentions an instruction tracing option but setting that env var, prior to anchor test does not seem to have any effect.


PS. If anyone wondering, this is not my issue.

2 Answers 2

2

"access violation" is a segfault. solana stack frames have a maximum size of 4kb; try wrapping some of the larger accounts in your Accounts struct with Box like in the snippet above (to allocate their data on the heap instead) and see if that resolves your problem


Example taken from an actual "stack size exceeded" issue due to an anchor version bump:

Before fix: Code leading to access violation (AuctionHouse allocated on stack)

#[derive(Accounts)]
#[instruction(buyer_price: u64, token_size: u64)]
pub struct ExecuteSale<'info> {
    ...
    #[account(signer)]
    authority: AccountInfo<'info>,
    #[account(...)]
    auction_house: Account<'info, AuctionHouse>,  // <-- Not boxed 
}

After fix: No more access violation (AuctionHouse allocated on heap)

#[derive(Accounts)]
#[instruction(buyer_price: u64, token_size: u64)]
pub struct ExecuteSale<'info> {
    ...
    #[account(signer)]
    authority: AccountInfo<'info>,
    #[account(...)]
    auction_house: Box<Account<'info, AuctionHouse>>,  // <-- Boxed `AuctionHouse` account
}
1
  • given the extra space that stack exchange offers, you could include a code example of a boxed account in the account struct
    – Henry E
    Jul 21 at 22:00
2

I found a way forward that I'll post for the benefit of others but it doesn't directly answer my question above so feel free to post more relevant answers and I will accept them over this one.

I scrolled further up to the anchor build (cargo build) part of the logs and I noticed the following:

Error: Function _ZN15primitive_types4U51215overflowing_pow17h7f88834a8e1c7feeE Stack offset of 4488 exceeded max offset of 4096 by 392 bytes, please minimize large stack variables

(You would have hoped the build process would stop at this error and won't continue to build and deploy the program, just so it will fail at runtime...)

Following the documentation, I demangled the name (although it is already kinda readable without):

λ rustfilt _ZN15primitive_types4U51215overflowing_pow17h49af1234973b300eE
primitive_types::U512::overflowing_pow

This has narrowed down where the error was somewhat. To my misfortune, it is coming from a dependency that I am actually using.

1
  • The reason that error doesn't fail normally: > The reason a warning is reported rather than an error is because some dependent crates may include functionality that violates the stack frame restrictions even if the program doesn't use that functionality. If the program violates the stack size at runtime, an AccessViolation error will be reported.
    – sohrab
    Jul 14 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.