blog > debugging segfaults with gdb (7 Dec 2025)
This "blogpost" is mainly just a reference/tutorial for my future self for when I'll have forgotten how to use gdb again.
I started using gdb to debug segfaults that occur on basdon, my gta:sa-mp server, which runs using things that I wrote in C.
plugins/basdonfly.so is my plugin for the samp server, which is
built with gcc using -ggdb to try to ensure enough debug information
is present.
I initially didn't get coredumps, so I had to execute
ulimit -c unlimited. Maybe "unlimited" should be some sane value
instead, but it works and I'm too lazy now. I also read that this is not
persistent, so I simply run this command right before starting the sa:mp server
every time.
With this configuration, I now get core.PID files on segfaults,
where PID is the process id. They are placed in the working directory.
I've also read somewhere - I think - that there may be a standard path set where
these files will be put, but it's not like that in my case.
gdb /basdon-fly/server/samp03svr -c core.8492
/basdon-fly/server/samp03svr is the samp server, a binary that I
did not build nor have debug symbols for.
-c core.8492 is the core dump file.
I'm not sure what the correct program argument is, should it be the server executable or my plugin shared library? It does not seem to matter much, but there has to be a program argument or it doesn't show much.
/basdon-fly/server/plugins/basdonfly.so instead of
samp03svr, the only difference that I can spot is that bt
shows a few (6) more calls, but they're all near the bottom of the stack and they
don't resolve to a known procedure so it doesn't help me much.
A quick info sharedlibrary should confirm that my plugin library was loaded and included symbols and debug info:
(gdb) info sharedlibrary From To Syms Read Shared Object Library No /lib/libdl.so.2 No /lib/libpthread.so.0 No /lib/libstdc++.so.6 No /lib/libm.so.6 No /lib/libgcc_s.so.1 No /lib/libc.so.6 0xf76f7058 0xf77124d3 Yes (*) /lib/ld-linux.so.2 No plugins/mysql-r39-3-static.so No /lib/librt.so.1 No /lib/libnss_files.so.2 No plugins/bcrypt-v2.2-debian7.so No plugins/simplesocket.so 0xf633aa00 0xf635bdd3 Yes plugins/basdonfly.so (*): Shared library is missing debugging information.
gdb finds commands using a "starts with" match, so
info locals could be shortened by doing
i lo.
If a command would be ambiguous, gdb will tell you.
At launch, gdb will already show the crash site.
Core was generated by `./samp03svr'. Program terminated with signal SIGSEGV, Segmentation fault. #0 spawn_get_random_spawn (playerid=playerid@entry=0, outSpawnInfo=outSpawnInfo@entry=0xffd0c9a2) at spawn.c:118 118 memcpy(&outSpawnInfo->pos, spawns[klass] + spawnidx, sizeof(struct vec4)); [Current thread is 1 (LWP 8492)]
bt shows a backtrace
(gdb) bt #0 spawn_get_random_spawn (playerid=playerid@entry=0, outSpawnInfo=outSpawnInfo@entry=0xffd0c9a2) at spawn.c:118 #1 0xf6348338 in natives_SpawnPlayer (playerid=playerid@entry=0) at samp.c:1443 #2 0xf6357cc3 in missions_cleanup (playerid=playerid@entry=0) at missions.c:820 #3 0xf6357e92 in missions_end_unfinished (playerid=playerid@entry=0, reason=reason@entry=1024) at missions.c:863 #4 0xf6357f5b in missions_on_vehicle_destroyed_or_respawned (vehicleid=vehicleid@entry=97) at missions.c:920 #5 0xf6357b8e in veh_DestroyVehicle (vehicleid=vehicleid@entry=97) at vehicles.c:1132 #6 0xf6359940 in B_OnVehicleSpawn (amx=0x84929d8, params=0xf63fd6a8) at basdonfly_callbacks.c:485 #7 0x08096a07 in ?? () #8 0x080a53b9 in ?? () #9 0x0814b674 in ?? () #10 0x0814cd5f in ?? () #11 0x080af078 in ?? () #12 0x080aa13a in ?? () #13 0xf73d91b3 in ?? ()
The frames in the backtrace are numbered, that number can be used to change
the current context with frame <number>
(gdb) frame 1 #1 0xf6348338 in natives_SpawnPlayer (playerid=playerid@entry=0) at samp.c:1443 warning: Source file is more recent than executable. 1443 spawn_get_random_spawn(playerid, &spawnInfo);
info locals shows local variables in the current frame
(gdb) info locals
spawnInfo = {team = 11 '\v', skin = -13156097, _pad5 = 69 'E', pos = {coords = {x = -nan(0x50c9b8), y = 4.2606904e-34,
z = 5.95649804e-34}, r = 1.35925951e-43}, weapon = {1764247626, -164267066, 139012568}, ammo = {-163641248, 8, 0}}
info args shows the arguments that were passed for
the proc in the current frame
(gdb) info args playerid = 0
print <expression> evaluates an expression. This can reference
global and local variables, arguments, ...
(gdb) p player[playerid]->pos
$9 = {x = -15495.7988, y = 11682.5537, z = -1.38694525}
info types shows all known types (includes typedefs and structures)
info shows all info subcommands
ptype <name> shows a type definition
(gdb) ptype struct STREAMING_DATA
type = struct STREAMING_DATA {
struct OBJECT_MAP *obj_map;
struct RPCDATA_CreateObject *queued_objects[900];
short num_queued_objects;
struct ZONE_MAP *zone_map;
short next_zone_idx;
}
(gdb) ptype enum OBJ_STREAM_MODE
type = enum OBJ_STREAM_MODE {OBJ_STREAM_MODE_ANY, OBJ_STREAM_MODE_CLOSEST_NOW}