├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── dctrace.py ├── main.c └── profiler.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.elf 3 | *.jpg 4 | *.txt 5 | *.dot 6 | *.bin 7 | .DS_Store 8 | .vscode/ 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2023, Dreamcast 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # What we are building 2 | TARGET = profile.elf 3 | 4 | # List of all source files 5 | SRCS = main.c profiler.c 6 | 7 | # List of files to exclude from instrumentation 8 | EXCLUDE_FILES = profiler.c 9 | 10 | # Set compiler flags 11 | CFLAGS = -g -finstrument-functions 12 | 13 | DATETIME := $(shell date '+%Y-%m-%d_%I-%M-%S_%p') 14 | 15 | all: clean $(TARGET) 16 | 17 | include $(KOS_BASE)/Makefile.rules 18 | 19 | clean: 20 | -rm -f $(TARGET) $(OBJS) 21 | -rm -f PROF.CDI 22 | -rm -rf ISO 23 | 24 | $(TARGET): $(SRCS) 25 | kos-cc $(CFLAGS) -finstrument-functions-exclude-file-list=$(EXCLUDE_FILES) $^ -o $@ $(DATAOBJS) $(OBJEXTRA) 26 | 27 | profileip: $(TARGET) 28 | sudo /opt/toolchains/dc-utils/dc-tool-ip -c "." -t 172.16.0.10 -x $(TARGET) 29 | 30 | profileser: $(TARGET) 31 | sudo /opt/toolchains/dc-utils/dc-tool-ser -c "." -t /dev/cu.usbserial-ABSCDWND -b 115200 -x $(TARGET) 32 | 33 | dot: trace.bin $(TARGET) 34 | python3 dctrace.py $(TARGET) 35 | 36 | image: dot 37 | dot -Tjpg graph.dot -o graph_$(DATETIME).jpg 38 | 39 | run: $(TARGET) 40 | $(KOS_IP_LOADER) $(TARGET) 41 | 42 | rei: dist 43 | $(REICAST) PROF.CDI 44 | 45 | lxd: dist 46 | $(LXDREAM) PROF.CDI 47 | 48 | fly: dist 49 | $(FLYCAST) PROF.CDI 50 | 51 | dist: $(target) 52 | $(KOS_STRIP) $(TARGET) 53 | $(KOS_OBJCOPY) -O binary $(TARGET) prog.bin 54 | $(KOS_SCRAMBLE) prog.bin 1ST_READ.BIN 55 | mkdir -p ISO 56 | cp 1ST_READ.BIN ISO 57 | mkisofs -C 0,11702 -V DCTEST -G ${KOS_BASE}/IP.BIN -J -R -l -o PROF.ISO ISO 58 | $(CREATE_CDI) PROF.ISO PROF.CDI 59 | rm -f PROF.ISO 60 | rm -f prog.BIN 61 | rm -f 1ST_READ.BIN 62 | rm -rf ISO 63 | rm $(TARGET) 64 | 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dcprofiler 2 | 3 | `dcprofiler` is a profiling toolkit for Dreamcast applications that uses GCC's `-finstrument-functions` feature to track function calls. It records detailed timing and performance counter data, generating a call graph visualization that highlights hotspots in your code. `dcprofiler` generates a lot of tracing data — use **dcload-ip for best performance**. 4 | 5 | There are two main parts to this project: 6 | 1. `profiler.c` – included in your Dreamcast project 7 | 2. `dctrace.py` – a Python script that parses `trace.bin` and generates a Graphviz `.dot` file 8 | 9 | --- 10 | 11 | ## Setup Instructions 12 | 13 | 1. **Add** `profiler.c` to your project’s source directory. 14 | 2. **Modify your Makefile**: 15 | - Add `-g -finstrument-functions` to `KOS_CFLAGS` 16 | - Add `profiler.o` to `OBJS` 17 | 3. **Upload your ELF** to the Dreamcast via dc-tool-ip: 18 | ```sh 19 | sudo /path/to/dc-tool-ip -c "." -t 192.168.1.137 -x program.elf 20 | ``` 21 | 4. **Run your Dreamcast app** - profiling begins immediately and stops on exit. The results are saved to trace.bin on your PC. 22 | 5. **Generate the call graph by running**: 23 | ```sh 24 | python3 dctrace.py [OPTIONS] program.elf 25 | ``` 26 | > **Note**: Make sure the following are true before running `dctrace.py`: 27 | > - `KOS_ADDR2LINE` is set **or** `sh-elf-addr2line` is located at `/opt/toolchains/dc/sh-elf/bin/` 28 | > - Your `trace.bin` and the corresponding `.elf` file are in the same directory 29 | 30 | 6. **Render the graph with Graphviz**: 31 | ```sh 32 | dot -Tpng graph.dot -o graph.png 33 | ``` 34 | 35 | ### Installing Graphviz 36 | 37 | To generate images from `.dot` files, you'll need to install the **Graphviz** tool. 38 | 39 | - Download it from the official site: [https://graphviz.org/download](https://graphviz.org/download) 40 | 41 | - On macOS (with Homebrew), run: 42 | ```sh 43 | brew install graphviz 44 | ``` 45 | 46 | ## dctrace.py Optional Flags 47 | 48 | The `dctrace.py` script accepts several options to customize the profiling output: 49 | 50 | | Option | Description | 51 | |---------------------|-----------------------------------------------------------------------------------------------------| 52 | | `-t ` | Specify the input trace file (default: `trace.bin`). | 53 | | `-a ` | Path to the `sh-elf-addr2line` tool (default: `/opt/toolchains/dc/sh-elf/bin/sh-elf-addr2line`). | 54 | | `-p ` | Percentage threshold for graph visibility. Functions below this inclusive time % are omitted. | 55 | | `-ev0="