nim-debugging
Skill4 starsChanged 3 months agoMITView on GitHub
Debug Nim compile failures, crashes, wrong results, macro expansion, ownership behavior, and unsafe-memory defects using focused reproduction, stack traces, inspection, compiler expansion, and sanitizers. Use when diagnosing runtime failures, release-only behavior, generic or macro issues, unexpected copies, pointer bugs, or memory leaks.
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- planetis-m/skillsedited, first seen Jul 16, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- planetis-m/skills★ 5997% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- atlas-package-clonerSkill
- buildSkill
- docs-genSkill
- format-codeSkill
- nim-api-designSkill
- nim-c-bindingsSkill
- nim-code-organizationSkill
- nim-c-wrappersSkill
- nim-defect-analysisSkill
- nim-doc-commentsSkill
- nim-error-handlingSkill
- nim-fuzzingSkill
- nim-mcp-toolsSkill
- nimonypluginsSkill
- nim-ownership-hooksSkill
- nim-style-guideSkill
- nim-testingSkill
- run-testsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 5 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 46
Add --lineTrace:on to the failing release or danger command to restore the call chain and line numbers.
- Very specific: line 48
Use --excessiveStackTrace:off when filenames are sufficient.
- Very specific: line 50
Call writeStackTrace() when the current path matters before an exception exists.
- Distinctive: line 52
Read the trace from the failure backward, then inspect values along that path until the first invalid state is found.
- Very specific: line 57
Use echo for ordinary values and repr when a type lacks useful $ formatting.
- Very specific: line 59
Use debugEcho inside {.noSideEffect.} code.
- Very specific: line 71
Run nim c --expandMacro:<name> file.nim to inspect a macro's expanded AST.
- Very specific: line 73
Run nim c --expandArc:<proc> file.nim to inspect injected copy, sink, move, and destroy operations.
- Very specific: line 75
Keep an --expandArc target reachable from the entry point and use the target project's --mm: mode.
- Very specific: line 79
Treat expansion output as evidence about generated operations, not as a reason to optimize by itself.
- Very specific: line 87
Use ASan for ptr, addr, cstring, cstringArray, manual allocation, and C-FFI memory faults.
- Distinctive: line 108
Read both the invalid-access stack and the allocation/free stack before editing code.
- Distinctive: line 116
Use Valgrind as an independent native-memory check:
- Distinctive: line 139
Follow the failing path backward and locate the first invalid state.
- Distinctive: line 142
Add a regression test, then remove temporary prints and scratch artifacts.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Nim Debugging
Debug by reducing uncertainty: preserve the failure, state one hypothesis, and collect the smallest piece of evidence that can reject it. Find the first violated invariant rather than stopping at the final crash.
Rules
Preserve the failure
- Record the exact input, command, working directory, backend, memory manager, thread setting, build mode, and relevant environment.
- Make the failure deterministic before changing code. If it is intermittent, preserve a seed, event order, or failing fixture.
- Change one diagnostic dimension at a time. A debug build that no longer fails is a comparison point, not a reproduction.
- Turn each confirmed defect into a regression test before removing instrumentation.
Choose evidence by failure class
| Failure | First evidence |
| Compile-time type or generic question | Normal compiler diagnostic; use compiles only for a yes/no probe |
| Unhandled exception or defect | Default stack trace, or --lineTrace:on in the failing optimized mode |
| Wrong runtime value | echo, debugEcho, or repr at invariant boundaries |
| Buffered output lost at a crash | stdout.write followed by stdout.flushFile() |
| Macro-generated code | --expandMacro:<name> |
| Unexpected copy, move, or destruction | --expandArc:<proc> under the project memory manager |
| Pointer, manual allocation, or FFI memory error | AddressSanitizer with the complete required recipe |
| Independent leak or invalid-access check | Valgrind |
Stack traces and build modes
Default build behavior:
| Mode | Unhandled exception trace | writeStackTrace() |
default or -d:debug | full paths and line numbers | full trace |
-d:release | raising frame only | no traceback available |
-d:danger | raising frame only | no traceback available |
- Add
--lineTrace:onto the failing release or danger command to restore the call chain and line numbers. It implies--stackTrace:on. - Use
--excessiveStackTrace:offwhen filenames are sufficient; the defaultonform includes full paths. - Call
writeStackTrace()when the current path matters before an exception exists. - Read the trace from the failure backward, then inspect values along that path until the first invalid state is found.
Runtime inspection
- Use
echofor ordinary values andreprwhen a type lacks useful$formatting. - Use
debugEchoinside{.noSideEffect.}code; ordinaryechois rejected there. echoflushes automatically. Flushstdout.writeexplicitly when a crash could occur before the buffer drains.- Label diagnostic values with the phase and invariant being checked. Avoid dumping large structures when one length, index, tag, or identity answers the hypothesis.
compiles(expr)is a compile-time boolean probe. If it returnsfalse, compile the candidate normally to obtain the actual diagnostic.
Compiler-generated code
- Run
nim c --expandMacro:<name> file.nimto inspect a macro's expanded AST. The compiler emits an[ExpandMacro]hint. - Run
nim c --expandArc:<proc> file.nimto inspect injected copy, sink, move, and destroy operations. - Keep an
--expandArctarget reachable from the entry point and use the target project's--mm:mode. - Measure copy behavior inside a named proc; last-use analysis does not fire at module top level.
- Treat expansion output as evidence about generated operations, not as a
reason to optimize by itself.
moveis destructive and requires deliberate last use plus behavior tests. - Nim defaults to ORC. Read the compiler build hint because project configuration may select ARC or atomic ARC.
AddressSanitizer
Use ASan for ptr, addr, cstring, cstringArray, manual allocation, and
C-FFI memory faults. The required Linux/GCC recipe is:
nim c \
--passC:"-fsanitize=address -fno-omit-frame-pointer" \
--passL:"-fsanitize=address -fno-omit-frame-pointer" \
-g \
-d:useMalloc \
-d:noSignalHandler \
file.nim- Pass sanitizer flags to both compilation and linking.
-d:useMallocis required so ASan observes memory obtained through Nim's allocator.-d:noSignalHandleris required so ASan, rather than Nim's signal handler, reports signal faults.-ggives symbolized Nim locations with GCC. Add--cc:clangfor Clang and ensurellvm-symbolizeris inPATH.- Preserve the project's memory manager and failing input.
- Read both the invalid-access stack and the allocation/free stack before editing code.
See references/memory_sanitizers.md for a complete runnable example. Platform
recipes not verified in this repository are intentionally omitted.
Valgrind
Use Valgrind as an independent native-memory check:
nim c -g -o:program file.nim
valgrind --leak-check=full --error-exitcode=1 ./programIt requires no sanitizer instrumentation and is slower than ASan. A non-zero exit distinguishes detected errors in automated checks.
Debug symbols and native debuggers
-gand--debugger:nativeenable native debug information and line directives.- This project does not use GDB: Nim name mangling and generated C make variable inspection slower and less reliable than stack traces, focused inspection, ASan, Valgrind, and compiler expansion.
Workflow
- Reproduce the failure with an exact command and fixed input.
- Minimize unrelated setup while keeping the same failure and configuration.
- State one falsifiable hypothesis and the invariant it predicts.
- Select the narrowest evidence source from the failure-class table.
- Follow the failing path backward and locate the first invalid state.
- Fix the invariant at its owner instead of suppressing the final symptom.
- Re-run the original reproduction and relevant sanitizer or expansion check.
- Add a regression test, then remove temporary prints and scratch artifacts.
Common Mistakes
| Mistake | Why it is wrong |
| Changing input, build mode, and code together | The result cannot identify which change affected the failure |
| Reading only the final crashing line | Corruption or invalid state commonly begins earlier |
| Expecting full traces from release or danger defaults | Add --lineTrace:on to the failing optimized command |
Using compiles as a replacement for compiler diagnostics | It answers only yes or no and suppresses the candidate diagnostic |
Printing with stdout.write immediately before a crash without flushing | Buffered evidence can be lost |
Running ASan without -d:useMalloc | Nim allocator overflows can remain invisible to ASan |
Running ASan without -d:noSignalHandler | Nim can intercept signal faults before ASan reports them |
| Passing ASan flags only to C compilation | The sanitizer runtime must also be linked |
Using Clang ASan without llvm-symbolizer | Reports can contain raw addresses instead of Nim locations |
Adding move merely because --expandArc shows a copy | move changes ownership semantics and must be safe at last use |
| Using GDB for routine Nim debugging | The project uses faster Nim-aware evidence sources instead |
References
references/stack_trace_diagnosis.md— Boundary instrumentation for finding the first bad value behind a crash.references/memory_sanitizers.md— ASan and Valgrind commands for unsafe access and leaks.references/arc_optimization.md—expandArccomparison for unexpected ownership copies.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

