Debugging
C Backend binaries (Default)
To debug issues in the generated binary (flag: -b c), you can pass these flags:
-g- produces a less optimized executable with more debug information in it. Generated C uses#linedirectives so debuggers and panic stacktraces resolve positions to the original .v files. It is usually better to pass -g, unless you are writing low-level code, in which case use the next option-cg.-cg- produces a less optimized executable with more debug information in it. The executable will use C source line numbers in this case. It is frequently used in combination with-keepc, so that you can inspect the generated C program in case of panic, or so that your debugger (gdb,lldbetc.) can show you the generated C source code. The C backend retains its per-build.<executable>.v3cc.*directory beside the executable so the source paths in the debug information remain available. You can remove this directory after debugging.-showcc- prints the C command that is used to build the program.-show-c-output- prints the output, that your C compiler produced while compiling your program.-keepc- do not delete the generated C source code file after a successful compilation. Also keep using the same file path, so it is more stable, and easier to keep opened in an editor/IDE.
On macOS, debug builds keep their .dSYM bundle beside the final executable.
For best debugging experience if you are writing a low-level wrapper for an existing
C library, you can pass several of these flags at the same time:
v -keepc -cg -showcc yourprogram.v, then just run your debugger (gdb/lldb) or IDE
on the produced executable yourprogram.
If you just want to inspect the generated C code,
without further compilation, you can also use the -o flag (e.g. -o file.c).
This will make V produce the file.c then stop.
If you want to see the generated C source code for just a single C function,
for example main, you can use: -printfn main -o file.c.
To debug the V executable itself you need to compile from src with ./v -g -o v cmd/v.
You can debug tests with for example v -g -keepc prog_test.v. The -keepc flag is needed,
so that the executable is not deleted, after it was created and ran.
To see a detailed list of all flags that V supports,
use v help, v help build and v help build-c.
Commandline Debugging
Troubleshooting (debugging) executables created with V in GDB
Visual debugging Setup:
Native Backend binaries
v self builds the compiler with only the C backend by default. Selecting another backend,
such as v -b arm64 file.v, automatically builds and runs a full compiler in the tool cache.
Later requests reuse it until its compiler or source dependencies change. VTOOLS_NO_CACHE=1
builds a temporary full compiler for each request instead. To include optional backends in v
itself, use v -compile-backend arm64 self or v -all-backends self.
-b native has been replaced by -b arm64 and -b x64. Use v -b arm64 file.v on macOS
ARM64 or v -b x64 file.v on Linux AMD64. The native backends do not link a garbage collector yet,
so they always
build as if -gc none was passed. For x64, -prod enables SSA optimization, scalar register
allocation, and optimized C helpers. Very large x64 modules may skip the global SSA pass to
bound compiler memory. The ARM64 backend retains its existing optimization behavior.
ARM64 executable linking is silent by default; use -stats to display compiler stage timings.
ARM64 builds reject native source files included with #include, #insert, #preinclude, or
#postinclude, because its linker cannot link those sources yet. Use the C backend for them.
ARM64 resolves a fixed set of platform C constants. Other C constants produce an error;
use the C backend when a header defines a constant the native backend does not support.
The supported set includes the memory-order and pthread compatibility constants used by
V's synchronization runtime.
The x64 backend is experimental. Calls without a native implementation fail compilation
or linking rather than producing placeholder implementations.
It requires a Linux AMD64 host. Passing or returning C structs and arrays by value is
currently unsupported and produces a diagnostic; pass pointers to C aggregates instead.
Stored C function values support integer and pointer arguments with 64-bit integer, pointer,
or void returns. Taking the address of a variadic C function, one with floating-point arguments
or returns, or one returning a narrower integer produces a diagnostic. Direct C calls retain
their scalar calling convention.
C callbacks passed to or returned from C functions support 64-bit integer and pointer
arguments, and 64-bit integer, pointer, or void returns. Unsupported callback conventions,
including floating-point, narrow integer, aggregate, and variadic signatures, produce a diagnostic.
Native 128-bit integers currently support integer widening, copying, bitwise &, |, ^,
addition, subtraction, comparisons, and shifts with constant counts from 0 through 127.
Signed scalar widening sign-extends for both i128 and u128; unsigned scalar widening
zero-extends.
Signed i128 >> preserves the sign; u128 >> and >>> fill with zeroes.
Multiplication, division, remainder, unary negation and complement, variable shifts,
compound assignments, increment/decrement, narrowing casts, and conversions to or from
floating-point values are unsupported and produce a diagnostic. Range iteration with 128-bit
values is also unsupported. Array and string indices and slice bounds must use scalar integers.
Integer literals must fit in a single 64-bit limb; construct larger values with shifts and
bitwise operations.
Use the C backend for the full set of 128-bit operations.
Currently there is no debugging support for binaries created by the native backends.
Javascript Backend
To debug the generated Javascript output you can activate source maps:
v -b js -sourcemap hello.v -o hello.js
For all supported options check the latest help:
v help build-js