Skip to main content
Use this page when you need to reason about what kind of C environment a Thru program actually runs in.

What environment you are in

Thru C programs run inside the Thru VM, not as normal hosted user-space processes. That means:
  • there is no conventional main
  • there is no argv or environment-variable interface
  • transaction, account, block, and shadow-stack data come from VM-mapped segments
  • control flow ends through tsdk_return, tsdk_revert, or tsys_exit

Memory model

Most of the public SDK reads are borrowed pointers into VM-managed memory:
  • tsdk_get_txn()
  • tsdk_get_account_meta(...)
  • tsdk_get_account_data_ptr(...)
  • tsdk_get_current_block_ctx()
  • tsdk_get_shadow_stack()
Treat these as borrowed views over runtime-managed memory, not heap allocations you own.

Hosted vs freestanding assumptions

The SDK is designed for freestanding builds targeting RISC-V. The toolchain links against picolibc, a lightweight C library for embedded targets. What the build files clearly establish:
  • programs are compiled as freestanding C, not hosted user-space binaries
  • the Thru VM machine config uses a picolibc sysroot
  • normal process and OS facilities are not part of the program model
What the build files do not guarantee:
  • that every familiar libc helper is available in every installed toolchain
  • that POSIX-style APIs are present
  • that you can treat the environment like a normal Linux process
Practical takeaway:
  • prefer SDK helpers first
  • assume extra libc usage needs to be validated against the installed toolchain
  • keep dependencies on non-SDK runtime facilities narrow and explicit

Facilities you should not assume exist

CategoryNotes
File I/ONo fopen, fread, printf (use tsdk_printf instead)
Dynamic memoryNo malloc, free, calloc, realloc
Process/OSNo exit, fork, getenv, signal
NetworkingNo sockets or network calls
ThreadsNo pthread, no concurrency primitives
Hosted runtime behaviorNo argv, environment variables, filesystem process model, or normal process startup/teardown

Floating-point expectations

The default Thru VM build target does not enable the RISC-V floating-point ISA extensions in its -march flags. Practical takeaway:
  • do not assume a full normal libc or POSIX environment
  • prefer SDK helpers and simple explicit code
  • be careful with patterns that rely on hosted-process facilities
  • prefer integer math unless you have validated that floating-point code is appropriate for your target and toolchain
  • use stack allocation or the anonymous segment syscalls for temporary memory

Temporary memory

For simple programs, stack allocation is often enough. If you need structured scratch-space carving, the SDK exposes:
  • TSDK_LAYOUT_INIT
  • TSDK_LAYOUT_APPEND
  • TSDK_LAYOUT_FINI
  • TSDK_SCRATCH_ALLOC_INIT
  • TSDK_SCRATCH_ALLOC_APPEND
  • TSDK_SCRATCH_ALLOC_FINI
These are safer than ad hoc pointer arithmetic when you need multiple aligned temporary regions.

Limits

LimitValueDefined as
Max account data size16 MBTSDK_ACCOUNT_DATA_SZ_MAX
tsdk_printf buffer1024 bytes per callInternal fixed buffer
Max CPI call depth17 framesTSDK_SHADOW_STACK_FRAME_MAX

Logging and output

There is no normal stdout or stderr channel in the usual process sense. Use:
  • tsdk_printf(...) for formatted debugging output (capped at 1024 bytes per call)
  • tsys_log(...) for raw log bytes
  • tsys_emit_event(...) for event payloads intended for downstream consumers

Alignment and raw byte parsing

When reading from raw instruction bytes or any layout with uncertain alignment:
  • prefer TSDK_LOAD
  • prefer TSDK_STORE
Direct casts are easier to get wrong in variable-length or tightly packed payloads.

Notes

  • If a task sounds like β€œnormal C application code,” the C SDK is probably the wrong layer.
  • If a task sounds like β€œVM entrypoint, account mutation, CPI, proof parsing, or instruction decoding,” this environment model is the right one.