K07 — TaskHandle_t, explicit start() and static trampoline
K07 isolates the exact C/C++ task-entry boundary. A local CounterTask object
is constructed without touching the FreeRTOS heap. Only an explicit start()
calls xTaskCreate() and passes the stable object address as void* context.
The kernel later calls a static, non-virtual trampoline, which recovers the
typed object and invokes its private run() member.
CounterTask object
-> start()
-> xTaskCreate(static trampoline, context=&object)
-> kernel chooses task
-> trampoline(void*)
-> static_cast<CounterTask*>(context)
-> object.run()
-> state=completed, handle=nullptr, vTaskDelete(nullptr)
The wrapper is non-copyable and non-movable because a live kernel task retains its object address. The destructor does not attempt asynchronous task deletion.
Three distinct address domains
The checked Hazard3 run records:
C++ object = 0x800fffcc (local object on the retained main stack)
TCB/handle = 0x800038b0 (dynamic kernel object in ucHeap)
task stack = 0x800034a0..0x80003890
result = 500500
The object address remains identical before start, in xTaskCreate context,
inside the trampoline, inside run() and at completion. The numeric handle is
the TCB address and is deliberately different from the C++ object.
Lifecycle evidence
| Point | Evidence |
|---|---|
| 1 | object constructed; heap unchanged; handle null |
| 2 | state starting inside explicit start |
| 3 | state ready; typed object passed as raw context |
| 4 | xTaskCreate returned; handle now identifies the TCB |
| 5 | scheduler not yet started; object still at same address |
| 6 | static trampoline receives the original object address |
| 7 | state running before member body |
| 8 | body records current handle, stack bounds and result |
| 10 | state completed, handle cleared, current task self-deletes |
| 11–12 | raw verifier checks identity/lifecycle and emits PASS |
Build
make check
Expected summary:
PASS host: explicit start, stable context, duplicate/failure states
PASS ABI: static trampoline; no vtable, RTTI or hosted runtime
PASS task01: explicit start + stable context + trampoline
Debug
b explicit_task_debug_checkpoint
p g_checkpoint_trace
p/x g_object_before_start
p/x g_trampoline_context
p/x g_run_this
p/x g_handle_after_start
p/x g_tcb_address
p/x g_stack_low
p/x g_stack_high
p/x g_stack_local
p g_counter_result
p g_task_wrapper_pass
Scope boundary
K07 uses dynamic kernel storage only to study entry and identity. K08 compares
dynamic and caller-supplied static TCB/stack policies and the timing of idle-task
cleanup. A Task destructor still does not force-delete a running task.