Getting started

This page is a hands-on tour of what visao does. It assumes that visao is on your PATH. Refer to Running the analyzer.

1. First C run

C is the primary language of the analyser. Create the canonical “hello world of static analysis” file:

 1int main()
 2{
 3    int a = 0;
 4
 5    if (a)
 6    {
 7        a = 5;
 8    }
 9    return 0;
10}

Then run the analyser against it:

visao c_test.c

The analyser prints output close to this:

1c_test.c:5:8: error: Condition is always false
2        if (a)
3        ^
4        {

The output is structured into three layers (see Console mode):

  • dim engine chatter at the top (Parsing 1 / 3..., Solving …);

  • a colour-coded report block for each defect, with file:line:col: error: <message> and a source excerpt;

  • a one-line final status (✓ Finished successfully · 316 ms).

For plain ASCII (for example for CI logs), pass --no-color or set NO_COLOR=1.

2. Compilation databases

Most modern build systems (cmake, meson, ninja, …) emit compile_commands.json, which lists each file in the workspace plus the exact compiler invocation. Visao accepts it as the sole positional argument and routes each entry through the toolchain inferred from its command:

1[
2    {
3        "directory": "/home/mmenshchikov/src/equid/build/fs",
4        "command": "/usr/bin/c++ -Iheaders",
5        "file": "/home/mmenshchikov/src/equid/build/fs/c_test.c"
6    }
7]

Run:

visao compile_commands.json

Header search paths, preprocessor defines and target triples all come from the compile DB. Supply the values that the build system does not record.

3. Filtering and severity

For a noisy run, pin the severity gate or restrict the analyzer to specific functions:

visao --severity Medium c_test.c
visao --verify-function process --verify-function helper -- src/*.c

4. Another language: Python

Every language has a front-end of its own (refer to Languages). The rules above the front-ends are shared, so Python reports the same defect classes as C. These classes cover values that can be absent and indexes past the end of a container. They also cover untrusted data that reaches a shell, and resources that stay open. The package carries pyright, which gives Visao the types of the program.

visao script.py

You install no compiler for Python. The extension selects the language, so the run needs no option.

5. Cross-compile target

Point the analyzer at a non-default GCC for cross-target probing:

visao --compiler-path "gcc:/opt/arm-none-eabi/bin/arm-none-eabi-gcc" \
      --cpu arm --os linux --language c \
      -I include -- firmware/*.c

On the very first run, expect a cold toolchain probe (~1 second). Subsequent runs use the user-level cache under $XDG_CONFIG_HOME/visao/tccache.txt.

6. Suspicious places

A finding states a defect. A suspicious place states that the code needs a reader. Examples: two identical arms of a branch, a name that differs from its declaration, and a password check.

visao --suspicious -- src/*.c
visao --suspicious-only --suspicious-categories security -- src/*.py

Visao prints each place with its category, its confidence and the lines of code around it. A suspicious place never changes the exit status. Refer to Suspicious places.

7. Server mode quickstart

To prepare visao for incremental client requests, start it as a server:

visao --update-toolchains              # one-off cache warmup
visao --server tcp://127.0.0.1:5500

The console shows Server is ready to receive incoming requests, and the process blocks. A client adds a workspace, attaches a file, starts an analysis, polls the state, and then tears it all down. For the protocol and the architecture see Server mode.

8. Dependency graph

To inspect zone/module structure of a project rather than its defects:

visao --dependency \
      --dep-graph-out out/deps.dot \
      --dep-graph-out-png out/deps.png \
      --language c -- src/*.c

The --dependency job is mutually exclusive with the default --defects unless you re-enable defects explicitly:

visao --defects --dependency --dep-graph-out out/deps.dot ...

9. Where to go next