1
0
mirror of https://github.com/pumpitupdev/pumptools.git synced 2024-11-24 15:00:12 +01:00
pumptools/doc/development/development.md

163 lines
6.6 KiB
Markdown

# Development
This document covers various aspects of developing for pumptools. For developing using the API, see
[the dedicated readme](../api/api.md).
## Architecture
[This document](architecture.md) gives an introduction to the architecture of pumptools. This helps you to get familiar
with the codebase and its features, definitely recommended to read this first.
## Development environment setup
Pumptools is written entirely in C and built using cmake. Various helper scripts are written as bash/shell scripts.
Therefore, you need the following tools on your development setup:
* gcc
* cmake
* make
* bash or compatible shell
Pumptools requires the following dependencies to be installed on your development OS:
* libcurl4 i386
* libusb 1.0 i386
Furthermore, header files, which come with the development packages of the libs, of the following libraries are
required:
* fmodex
* libconfig
* X11
* libalsa
* libusb-0.1 (**not** 1.0)
The project does not depend on any specific IDE. However, if you use CLion, the project can be imported easily.
## Code style
The main style guidelines are defined by the `.clang-format` file and the code style can be easily applied to the
whole `src` directory using the following command from the root folder:
```shell script
make clang-format
```
Make sure that your contributions follow the style and apply it before submitting your changes.
For other source files like shell scripts, cmake, makefile or markdown documents, please follow the already established
style in the existing documents.
## Building
See the [main readme](../../README.md#building).
## Compatibility issues with newer glibc versions
We have experienced various issues with different glibc versions which had a major impact on the builds. The following
table gives you a list of tested glibc versions and issues that are either present or not with each version listed.
"ok" indicates that the specified glibc version is compatible and the specific issue does not occur, "bad" indicates
incompatibility and that the specific issue does occur when using a binary compiled with that glibc version.
| Issue/glibc version | 2.23 | 2.30 |
|---------------------|------|------|
| Issue 1 | ok | bad |
| Issue 2 | ok | bad |
The issues are further described in the following sub-sections
### Issue 1: Crash during static initialization
For a detailed report on this issue, see the [dedicated notes](notes/f2-crashing-on-modern-linux-post-mortem.md).
Summarized: Fiesta 2 and newer will segfault before even running the application's main method. The application fails
on runtime initialization when initializing the static context. This is caused by ABI incompatibility of inlined code
of C++'s STL, first occurring with string allocations during static initialization.
### Issue 2: sscanf not being detoured
With NX2, Andamiro locked the USB drives to be used to a specific brand which they sold back then. That lock is patched
out by detouring `sscanf` and manipulating the VID/PID and serial number parsing logic in the game to always return
the values, the game wants to see to accept the connected USB drive.
However, some incompatibility on newer glibc versions does not setup the `sscanf` detour properly. The detour function
is there and gets called by various parts of the game code in the beginning, but later calls to `sscanf` always go
to the real function instead. Thus, the usb unlock feature does not work.
## Unit tests
Unfortunately, this was started very late in the development of pumptools, but it's not too late to keep extending this
with every change to ensure existing features don't break and future ones work.
When you have a change to commit, check if there is an existing unit-test which needs to be aligned with your change(s).
If not, create one.
For testing code that gets hooked, there is a specific pattern that needs to be applied in order to allow testing
hooks without having to actually hook them. As an example, you can take a look at the
[usb-fix module](../../src/main/hook/propatch/usb-fix.h) for piu pro and the
[corresponding test](../../src/test/hook/propatch/usb-fix/main.c). It shows you how to setup the hooks and create
mocks for the functions that you can trap the calls to the real detoured functions to check if they are getting called
or return fixed values for testing.
## Debugging
### Pumptool's built-in tooling
Pumptools has a few basic debugging features built in which helps analyzing common issues very quickly without the
need of external tools.
#### Help and usage message of hook library
When running a game with any of pumptools's `hook.so` libs attached, you can always add the parameter `-h` to display a
help/usage message with all available command line and configuration parameters.
For example, when using `piueb` for bootstrapping:
```
./piueb run -h
```
The `-h` is passed on as a parameter and appended to the execution command. You can make use of that with other
available cmd parameters as well (see usage information).
#### Logging
Logging to console and file as well as the level of verbosity can be controlled using the `hook.conf` configuration file
or via command line arguments provided on execution.
All hooks implement various sanity checks for parameters provided, file checks etc. so there is a good coverage of
common mistakes and misconfiguration that can be easily detected by watching out for any ERROR or WARNING level messages
showing up in the log.
Example in configuration file:
```
util.log.file=pumptools.log
util.log.level=4
```
Furthermore, `piueb` outputs a separate log file `piueb.log` which contains logging data of the environment setup
process of `piueb`.
#### File and IO hook monitoring
In the configuration file or via cmd args, you can enable monitoring of file, filesystem, usb and/or open system calls
for tracing and debugging. This can be useful, to check if the game cannot find certain files like game assets.
Example in configuration file:
```
patch.hook_mon.file=0
patch.hook_mon.fs=0
patch.hook_mon.io=0
patch.hook_mon.open=1
patch.hook_mon.usb=0
```
#### Halt on SIGSEGV and attach debugger
Also enabled via configuration or cmd args, the application is halted on SIGSEGV to allow attaching a debugger.
Example in configuration file:
```
patch.sigsegv.halt_on_segv=1
```
### External tooling
#### Remote debugging
You can run the application with `gdbserver` using `piueb`:
```shell script
./piueb debug
```
And connect with your favorite debugger (e.g. IDA).
#### strace
You can run the application with `strace` using `piueb`:
```shell script
./piueb strace
```
#### valgrind
You can run the application with `valgrind` using `piueb`:
```shell script
./piueb valgrind
```