From 856c57a0f3cf94a4f7711a3491b01401cde4ef56 Mon Sep 17 00:00:00 2001 From: Adam Bratschi-Kaye Date: Wed, 19 Feb 2025 18:30:06 +0100 Subject: [PATCH] docs(EXC-1744): Document canister backtraces (#5185) * docs(EXC-1744): Document canister backtraces * link to log visibility * fix log link * Update docs/developer-docs/smart-contracts/maintain/backtraces.mdx Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> * Update docs/developer-docs/smart-contracts/maintain/backtraces.mdx Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> * Update docs/developer-docs/smart-contracts/maintain/backtraces.mdx Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> * Update docs/developer-docs/smart-contracts/maintain/backtraces.mdx Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> * Update docs/developer-docs/smart-contracts/maintain/backtraces.mdx Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> --------- Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> --- .github/CODEOWNERS | 5 +- .../smart-contracts/maintain/backtraces.mdx | 79 +++++++++++++++++++ sidebars.js | 1 + 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 docs/developer-docs/smart-contracts/maintain/backtraces.mdx diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 713b33b8ed..9d6545af95 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,9 +13,10 @@ docs/developer-docs/web-apps/custom-domains @dfinity/boundary-node docs/developer-docs/web-apps/http-compatible-canisters @dfinity/trust # Each piece of documentation must be owned by the respective teams -docs/developer-docssmart-contracts/advanced-features/simd.mdx @dfinity/execution -docs/developer-docssmart-contracts/advanced-features/periodic-tasks.mdx @dfinity/execution +docs/developer-docs/smart-contracts/advanced-features/simd.mdx @dfinity/execution +docs/developer-docs/smart-contracts/advanced-features/periodic-tasks.mdx @dfinity/execution docs/developer-docs/smart-contracts/best-practices/idempotency.mdx @dfinity/research @dfinity/product-security +docs/developer-docs/smart-contracts/maintain/backtraces.mdx @dfinity/execution # The Interface Specification docs/references/_attachments/certificates.cddl @dfinity/canister-os diff --git a/docs/developer-docs/smart-contracts/maintain/backtraces.mdx b/docs/developer-docs/smart-contracts/maintain/backtraces.mdx new file mode 100644 index 0000000000..a2cb29f23a --- /dev/null +++ b/docs/developer-docs/smart-contracts/maintain/backtraces.mdx @@ -0,0 +1,79 @@ +--- +keywords: [intermediate, tutorial, maintain canisters, logs, logging, backtraces, debugging, trap, canister trap] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import { GlossaryTooltip } from "/src/components/Tooltip/GlossaryTooltip"; + +# Canister backtraces + + + + +When canisters trap, ICP reports backtraces that contain the names of functions in the call stack. Backtraces are added to the canister logs and if the caller has [access to canister logs](/docs/current/developer-docs/smart-contracts/maintain/logs#log-visibility) they will also be included in the message error response. + +For example, if the following Rust canister accidentally performs an out of bounds access of stable memory: + +``` + #[update] + fn outer() { + inner(); + } + + fn inner() { + inner_2(); + } + + fn inner_2() { + ic_cdk::api::stable::stable_write(0xdeadbeef, b"foo") + } +``` + +The resulting stable memory out of bounds error will also contain the following backtrace which can help determine that the error is in `inner_2` which is reached via `outer` and `inner`: + +``` +Canister Backtrace: +ic0::ic0::stable64_write +_wasm_backtrace_canister::inner_2 +_wasm_backtrace_canister::inner +_wasm_backtrace_canister::outer +``` + + + +## Checking for canister support + +Backtrace support relies on function names being stored in the `name` [custom section](https://webassembly.github.io/spec/core/appendix/custom.html#name-section) of the canister Wasm module. +Any canister built with dfx version `>= 0.24.2` should automatically have support for backtraces. If you're manually altering your canister Wasm code with the `ic-wasm shrink` or `ic-wasm metadata` commands, you'll need to add the `--keep-name-section` flag to ensure the canister can still provide backtraces. + +To double check that a Wasm module has the name section, you can use [`wasm-objdump`](https://github.com/WebAssembly/wabt): + +``` +$ wasm-objdump -h test.wasm + +test.wasm: file format wasm 0x1 + +Sections: + + Type start=0x0000000a end=0x00000086 (size=0x0000007c) count: 18 + Import start=0x00000089 end=0x0000011f (size=0x00000096) count: 4 + Function start=0x00000122 end=0x000001da (size=0x000000b8) count: 182 + Table start=0x000001dc end=0x000001e1 (size=0x00000005) count: 1 + Memory start=0x000001e3 end=0x000001e6 (size=0x00000003) count: 1 + Global start=0x000001e8 end=0x000001f1 (size=0x00000009) count: 1 + Export start=0x000001f3 end=0x00000234 (size=0x00000041) count: 5 + Elem start=0x00000236 end=0x0000028d (size=0x00000057) count: 1 + Code start=0x00000291 end=0x0000ab1f (size=0x0000a88e) count: 182 + Data start=0x0000ab22 end=0x0000b990 (size=0x00000e6e) count: 2 + Custom start=0x0000b993 end=0x0000bad8 (size=0x00000145) ".debug_loc" + Custom start=0x0000badb end=0x0000cbf0 (size=0x00001115) ".debug_abbrev" + Custom start=0x0000cbf4 end=0x0007a78e (size=0x0006db9a) ".debug_info" + Custom start=0x0007a792 end=0x000a9000 (size=0x0002e86e) ".debug_ranges" + Custom start=0x000a9004 end=0x001542b4 (size=0x000ab2b0) ".debug_str" + Custom start=0x001542b8 end=0x0019ff04 (size=0x0004bc4c) ".debug_pubnames" + Custom start=0x0019ff07 end=0x001a0567 (size=0x00000660) ".debug_pubtypes" + Custom start=0x001a056b end=0x001e3464 (size=0x00042ef9) ".debug_line" + Custom start=0x001e3467 end=0x001e60a6 (size=0x00002c3f) "name" <-------------- Verify this section exists. + Custom start=0x001e60a9 end=0x001e6153 (size=0x000000aa) "producers" + Custom start=0x001e6155 end=0x001e618e (size=0x00000039) "target_features" +``` \ No newline at end of file diff --git a/sidebars.js b/sidebars.js index 3ef6362649..f01e8b71bf 100644 --- a/sidebars.js +++ b/sidebars.js @@ -165,6 +165,7 @@ const sidebars = { "developer-docs/smart-contracts/maintain/storage", "developer-docs/smart-contracts/maintain/trapping", "developer-docs/smart-contracts/maintain/upgrade", + "developer-docs/smart-contracts/maintain/backtraces", { type: "category", label: "Topping up canisters",