fte-team / fteqw

This is the official GitHub mirror for the FTEQW project.
https://www.fteqw.org/
180 stars 55 forks source link

FS_NativePath problems in loading plugin OpenBSD #135

Closed Xylemon closed 1 year ago

Xylemon commented 1 year ago

https://sourceforge.net/p/fteqw/tickets/93/

namtsui wrote on 2020-09-04:

eukara recommended that libexec be used for the OpenBSD port so that plugins could be loaded there. I came across a bug in filepath naming that prevented plugins from loading.

while trying to have /usr/local/libexec/fte contain the binaries:

$ ls /usr/local/libexec/fte/    
fteplug_ezhud.so    fteqcc              fteqw               fteqw-sv

with a shell script to launch it:

$ cat /usr/local/bin/fteqw
!/bin/sh

cd /usr/local/libexec/fte && ./fteqw "$@"

solution:

$OpenBSD$

Index: engine/common/fs.c
--- engine/common/fs.c.orig
+++ engine/common/fs.c
@@ -2058,7 +2058,7 @@ qboolean FS_NativePath(const char fname, enum fs_rela
if (host_parms.binarydir && host_parms.binarydir)
snprintf(out, outlen, "%s%s", host_parms.binarydir, fname);
else
- snprintf(out, outlen, "%s%s", host_parms.basedir, fname);
+ snprintf(out, outlen, "%s/%s", host_parms.basedir, fname);
break;
case FS_ROOT:
if (com_installer)

I set a breakpoint here: https://sourceforge.net/p/fteqw/code/HEAD/tree/trunk/engine/common/plugin.c#l209

debug dump (where I use emacs to step through so it doesn't show up):

(gdb) print newplug
$18 = {name = 0x2d42009c498 "ezhud", filename = "/usr/local/libexec/qwfteplug_ezhud_amd64.so", '\000' <repeats 980="" times="">, lib = 0x0, tick = 0x0, executestring = 0x0, consolelink = 0x0, consolelinkmouseover = 0x0, conexecutecommand = 0x0, menufunction = 0x0, sbarlevel = {0x0, 0x0, 0x0}, reschange = 0x0, connectionlessclientpacket = 0x0, svmsgfunction = 0x0, chatmsgfunction = 0x0, centerprintfunction = 0x0, mayshutdown = 0x0, shutdown = 0x0, next = 0x0}
(gdb) print newplug->filename
$19 = "/home/namtsui/games/data/quake/fteplug_ezhud_amd64.so", '\000' <repeats times="" 970="">
(gdb) print </repeats></repeats>newplug
$20 = {name = 0x2d42009c498 "ezhud", filename = "/home/namtsui/games/data/quake/fteplug_ezhud_amd64.so", '\000' <repeats times="" 970="">, lib = 0x0, tick = 0x0, executestring = 0x0, consolelink = 0x0, consolelinkmouseover = 0x0, conexecutecommand = 0x0, menufunction = 0x0, sbarlevel = {0x0, 0x0, 0x0}, reschange = 0x0, connectionlessclientpacket = 0x0, svmsgfunction = 0x0, chatmsgfunction = 0x0, centerprintfunction = 0x0, mayshutdown = 0x0, shutdown = 0x0, next = 0x0}
(gdb) print i
$21 = 1
(gdb) print newplug->lib
$22 = (void ) 0x0
(gdb) print newplug
$23 = (plugin_t ) 0x2d42009c000
(gdb) print *newplug
$24 = {name = 0x2d42009c498 "ezhud", filename = "/home/namtsui/games/data/quake/fteplug_ezhud_amd64.so", '\000' <repeats times="" 970="">, lib = 0x0, tick = 0x0, executestring = 0x0, consolelink = 0x0, consolelinkmouseover = 0x0, conexecutecommand = 0x0, menufunction = 0x0, sbarlevel = {0x0, 0x0, 0x0}, reschange = 0x0, connectionlessclientpacket = 0x0, svmsgfunction = 0x0, chatmsgfunction = 0x0, centerprintfunction = 0x0, mayshutdown = 0x0, shutdown = 0x0, next = 0x2d42cf2a800}
~~~</repeats></repeats>

I have a /usr/local/libexec/qw/fteplug_ezhud_amd64.so at this point in debugging (I eventually settled on /usr/local/libexec/fte/fteplug_ezhud.so). I also had fteplug_ezhud_amd64.so in /home/namtsui/games/data/quake/fteplug_ezhud_amd64.so.

libexec had an incorrect path (note no slash after qw): /usr/local/libexec/qwfteplug_ezhud_amd64.so but it was able to load the plugin in -basedir: /home/namtsui/games/data/quake/fteplug_ezhud_amd64.so

Xylemon commented 1 year ago

namtsui wrote on 2020-09-04:

Sorry for the broken formatting. Here I repaste solution that worked for me, but I am unsure if it will break other filesystem paths:

solution:

$OpenBSD$

Index: engine/common/fs.c
--- engine/common/fs.c.orig
+++ engine/common/fs.c
@@ -2058,7 +2058,7 @@ qboolean FS_NativePath(const char fname, enum fs_rela
if (host_parms.binarydir && host_parms.binarydir)
snprintf(out, outlen, "%s%s", host_parms.binarydir, fname);
else
- snprintf(out, outlen, "%s%s", host_parms.basedir, fname);
+ snprintf(out, outlen, "%s/%s", host_parms.basedir, fname);
break;
case FS_ROOT:
if (com_installer)
Xylemon commented 1 year ago

namtsui wrote on 2020-09-04:

Here I step into FS_NativePath and see that relativeto is set to FS_BINARYPATH. Eventually out is written missing slash in path: /usr/local/libexec/qwfteplug_ezhud_amd64.so

(gdb) run
Starting program: /usr/local/libexec/qw/fteqw -basedir ~/games/data/quake
[Switching to thread 1 (thread 128644)](running)
[New thread 310335]
[New thread 572420]
[New thread 179982]
[New thread 426655]

Thread 1 hit Breakpoint 4, Plug_Load (file=0xf92404ab0cc "fteplug_ezhud_amd64.so") at common/plugin.c:209
209             if (!Q_strncasecmp(file, PLUGINPREFIX, strlen(PLUGINPREFIX)))
(gdb) print i
$68 = 0
(gdb) print *newplug
$69 = {name = 0xf926823fc98 "ezhud", filename = '\000' <repeats 1023 times>, lib = 0x0, tick = 0x0, executestring = 0x0, consolelink = 0x0, consolelinkmouseover = 0x0, conexecutecommand = 0x0, menufunction = 0x0, sbarlevel = {0x0, 0x0, 0x0}, reschange = 0x0, connectionlessclientpacket = 0x0, svmsgfunction = 0x0, chatmsgfunction = 0x0, centerprintfunction = 0x0, mayshutdown = 0x0, shutdown = 0x0, next = 0x0}
(gdb) print prefixes[i]
$70 = FS_BINARYPATH
(gdb) print relativeto
$71 = FS_BINARYPATH
(gdb) print fname
$72 = 0xf92404ab0cc "fteplug_ezhud_amd64.so"
(gdb) print fname
$73 = 0x7f7ffffe1810 "fteplug_ezhud_amd64.so"
(gdb) print host_parms.basedir
$74 = 0xf921e99dde0 "/usr/local/libexec/qw"
(gdb) print fname
$75 = 0x7f7ffffe1810 "fteplug_ezhud_amd64.so"
(gdb) print outlen
$76 = 1024
(gdb) print out
$77 = 0xf926823f808 ""
(gdb) print out
$78 = 0xf926823f808 "/usr/local/libexec/qwfteplug_ezhud_amd64.so"
(gdb) 
namtsui commented 1 year ago

you can close this. it works testing against latest git version on openbsd.