-
Notifications
You must be signed in to change notification settings - Fork 43
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
testutils backtraces are usually not useful #1266
Comments
Hmm. This is sad. I would prefer to try stashing in the panic slot in the native frame. I'm sympathetic to this being quite frustrating and hard to follow. IME fixing these sorts of bugs takes a lot of careful tracing of the propagation paths before you find a change that'll do the trick. Where are the |
I want to spend some more time debugging. I have looked at the code that is intended to propagate errors, see that it could/should be able to proparage this backtrace, but don't quite have the full picture. In this case I am having the token client call a native-compiled contract, which makes an (It's at this point that I think There is surely some way to get I think I can figure this out myself, just need some more time to poke at it. |
Changing the TestContractFrame's panic slot to hold a Here's a wip patch that does so: brson@7cdcbab |
It wasn't actually literally converting to |
I've done a little more work on this here: https://github.com/brson/rs-soroban-env/tree/backtraces2 I've found 3 cases where a secondary error event discards the backtrace from the initial error event. One of them I have captured in a test case. |
This issue I have encountered repeatedly when debugging fuzzing errors, but is a bit hard to explain.
In various situations where an error is returned but not expected, the host calls
reject_error
, and in the testutils configuration, this mode logs diagnostics and dumps a backtrace. This backtrace though does not locate the original source of the error - it only locates the source of the call toreject_error
.The backtrace is mostly useless: the most effective way to find the actual source of the error is to read the diagnostics and hope one of them contains a greppable string. And then if you do locate the source of the error, you still don't have the backtrace that lead to that error. I almost always end up instrumenting the runtime and contracts with
println
s to actually figure out the call path to the error.Example:
In some recent tests I triggered this error in
Storage::extend
:The end result is that I see this output:
The backtrace doesn't indicate where that storage error was, just that something happened during the call to the token contract.
Something interesting here is that the original error does appear to generate a backtrace that we don't get to see: it calls
Host::err
, which produces aHostError
containing a backtrace (inmaybe_get_debug_info
):This
HostError
is not the one that ultimately gets printed. Instead,escalate_error_to_panic
creates a newHostError
and prints that:This new
HostError
generates the useless backtrace.It's not obvious though how to thread the backtrace from the original error all the way to this
escalate_error_to_panic
function (theHostError
received as input to this function is still not the original error, as the errors go through multiple layers of possibly-lossy translation fromHostError
toScError
and back; reusing the inputHostError
s backtrace would be more useful than the one that is printed though, and in some cases may be the actual desired backtrace).At the time the original error is generated, diagnostics are also logged, so there's an opportunity there to stash a backtrace in the diagnostics; then (somehow) figure out that particular diagnostic contains the backtrace of interest.
The text was updated successfully, but these errors were encountered: