diff --git a/README.md b/README.md index 23bc2ff..a108ac5 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,38 @@ vardbg replay qsort.json -v sort_vis.mp4 It is possible to generate videos live while running the debugged program, but this is discouraged because the overhead of video creation inflates execution times greatly and thus ruins profiler results. However, if profiling is not important to you, it is a valid use case. +### Step-by-Step Example (Common Pitfalls Explained) + +This section provides a minimal working example and explains common errors reported by new users. + +#### 1. Example Python file + +Ensure the function you want to debug exists and matches the name provided in the command. + +Example: `qsort.py` + +```python +def quick_sort(arr): + if len(arr) <= 1: + return arr + pivot = arr[0] + left = [x for x in arr[1:] if x <= pivot] + right = [x for x in arr[1:] if x > pivot] + return quick_sort(left) + [pivot] + quick_sort(right) + + +### Generating and Replaying a Trace + +The `replay` command requires a JSON trace file. +This file must be generated first using `vardbg run`. + +```bash +vardbg run qsort.py quick_sort -o qsort.json -a 9 -a 3 -a 5 -a 1 + +To generate a visualization video from the trace: +vardbg replay qsort.json -v qsort.mp4 + + ## Configuration The video generator has many options: resolution, speed, fonts, and sizes. These options can be modified using a [TOML](https://learnxinyminutes.com/docs/toml/) config file. The [default config](https://github.com/CCExtractor/vardbg/blob/master/vardbg/output/video_writer/default_config.toml) documents the available options, which can be customized in an minimal overlay config without having to duplicate the entire config. The config can then be used by passing the `-c` argument on the command line. @@ -90,3 +122,11 @@ Specifying the name of the variable may appear to be redundant, but there are tw Feel free to contribute to this project! You can add features, fix bugs, or make any other improvements you see fit. We just ask that you follow the [code style guidelines](https://github.com/CCExtractor/vardbg/blob/master/CODE_STYLE.md) to keep the code consistent and coherent. These guidelines can easily be enforced before pushing with the [pre-commit](https://pre-commit.com/) framework, which can install Git pre-commit hooks with the `pre-commit install` command. Once your contribution meets the guidelines, [open a pull request](https://github.com/CCExtractor/vardbg/compare) to make things official. + + +## Fuzzing + +Experimental fuzzing harnesses live under `fuzz/`. +They intentionally load individual modules (e.g. `data.py`) in isolation +to avoid pulling in heavy rendering and video dependencies, keeping fuzz +targets fast and focused. diff --git a/fuzz/fuzz_frameinfo.py b/fuzz/fuzz_frameinfo.py new file mode 100644 index 0000000..bd292b1 --- /dev/null +++ b/fuzz/fuzz_frameinfo.py @@ -0,0 +1,56 @@ +""" +Fuzz target for FrameInfo in vardbg/data.py. +Focuses on file access, line indexing, and comment parsing. +""" + + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(ROOT)) + +import tempfile +from types import SimpleNamespace + +import importlib.util +DATA_PATH = ROOT / "vardbg" / "data.py" +spec = importlib.util.spec_from_file_location("vardbg_data", DATA_PATH) +vardbg_data = importlib.util.module_from_spec(spec) +spec.loader.exec_module(vardbg_data) +FrameInfo = vardbg_data.FrameInfo + +def fuzz_input(data: bytes): + try: + # Decode fuzz data safely + text = data.decode("utf-8", errors="ignore") + + # Create a temporary file with fuzzed content + with tempfile.NamedTemporaryFile(delete=False, mode="w") as f: + f.write(text) + fname = f.name + + # Fake a frame-like object + fake_frame = SimpleNamespace( + f_code=SimpleNamespace( + co_name="fuzz_func", + co_filename=fname + ), + f_lineno=len(text.splitlines()) or 1 + ) + + file_cache = {} + FrameInfo(fake_frame, file_cache=file_cache) + + except Exception: + # Crashes are expected in fuzzing + pass + + +def main(): + data = sys.stdin.buffer.read() + fuzz_input(data) + + +if __name__ == "__main__": + main()