Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MLX support does not seem to work with nix version #110

Open
jukefr opened this issue Dec 11, 2024 · 6 comments
Open

MLX support does not seem to work with nix version #110

jukefr opened this issue Dec 11, 2024 · 6 comments
Assignees

Comments

@jukefr
Copy link

jukefr commented Dec 11, 2024

Describe the bug
I was trying to test my so_long project (which uses MinilibX).
If I run funcheck on for example get_next_line it works fine.
If I run it on my so_long project, it seems to hang forever.

To Reproduce
Steps to reproduce the behavior:

  1. Use a so_long project as base (or any project that uses Minilibx)
  2. Build it (I use this flake to build my so_long)
  3. Run funcheck ./<bin> <args>

Expected behavior
It should not hang.

Screenshots
image

Additional context
For exact reproduction steps:
as development shell

git clone https://codeberg.org/juke/so_long.git && cd so_long
nix develop "git+https://codeberg.org/juke/42-flakes.nix?dir=so_long" --refresh --no-write-lock-file
# inside development shell
make
funcheck ./so_long maps/map1.ber

or as direct build

git clone https://codeberg.org/juke/so_long.git && cd so_long
nix build "git+https://codeberg.org/juke/42-flakes.nix?dir=so_long" --refresh --no-write-lock-file --impure
funcheck ./result/bin/so_long maps/map1.ber
@jukefr
Copy link
Author

jukefr commented Dec 11, 2024

seems to be any x11 stuff actually, not specifically mlx

i tried this simple gist https://gist.githubusercontent.com/m1nuz/8f8f10a7f8715b62fe79/raw/ac438bd5d757e82c1781d462bfa9be15d657ae31/simple-x11-window.c

and built it with -lX11 and funcheck also hangs on it

@jukefr
Copy link
Author

jukefr commented Dec 11, 2024

heres the last lines of an strace with no fork following

pipe2([3, 6], 0)                        = 0
openat(AT_FDCWD, "/tmp", O_RDWR|O_EXCL|O_TMPFILE, 0600) = 7
fcntl(7, F_GETFL)                       = 0x418002 (flags O_RDWR|O_LARGEFILE|O_TMPFILE)
getpid()                                = 881499
openat(AT_FDCWD, "/dev/shm/funcheck_881499_1733907434_0", O_RDWR|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0666) = 8
ftruncate(8, 1176)                      = 0
mmap(NULL, 1176, PROT_READ|PROT_WRITE, MAP_SHARED, 8, 0) = 0x7ffff7dbc000
close(8)                                = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7ffff7e4dcd0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0x7ffff7e00620}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7ffff75bb000
mprotect(0x7ffff75bc000, 8388608, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x7ffff7dbb990, parent_tid=0x7ffff7dbb990, exit_signal=0, stack=0x7ffff75bb000, stack_size=0x7fff80, tls=0x7ffff7dbb6c0} => {parent_tid=[881502]}, 88) = 881502
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
dup(0)                                  = 8
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7ffff6dba000
mprotect(0x7ffff6dbb000, 8388608, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x7ffff75ba990, parent_tid=0x7ffff75ba990, exit_signal=0, stack=0x7ffff6dba000, stack_size=0x7fff80, tls=0x7ffff75ba6c0} => {parent_tid=[881503]}, 88) = 881503
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7ffff7dbda10) = 881504
close(3)                                = 0
wait4(881504,

heres the last lines of an strace with fork following

[pid 882162] read(5,  <unfinished ...>
[pid 882161] write(1, "main\n??:0:0\n\n", 13 <unfinished ...>
[pid 882162] <... read resumed>"main\n??:0:0\n\n", 4096) = 13
[pid 882161] <... write resumed>)       = 13
[pid 882162] write(4, "0x5a0e\n", 7 <unfinished ...>
[pid 882161] read(0,  <unfinished ...>
[pid 882162] <... write resumed>)       = 7
[pid 882161] <... read resumed>"0x5a0e\n", 4096) = 7
[pid 882162] read(5,  <unfinished ...>
[pid 882161] write(1, "??\n??:0:0\n\n", 11 <unfinished ...>
[pid 882162] <... read resumed>"??\n??:0:0\n\n", 4096) = 11
[pid 882161] <... write resumed>)       = 11
[pid 882162] write(4, "0x2a27d\n", 8 <unfinished ...>
[pid 882161] read(0,  <unfinished ...>
[pid 882162] <... write resumed>)       = 8
[pid 882161] <... read resumed>"0x2a27d\n", 4096) = 8
[pid 882162] read(5,  <unfinished ...>
[pid 882161] write(1, "??\n??:0:0\n\n", 11 <unfinished ...>
[pid 882162] <... read resumed>"??\n??:0:0\n\n", 4096) = 11
[pid 882161] <... write resumed>)       = 11
[pid 882162] write(4, "0x2a338\n", 8 <unfinished ...>
[pid 882161] read(0,  <unfinished ...>
[pid 882162] <... write resumed>)       = 8
[pid 882161] <... read resumed>"0x2a338\n", 4096) = 8
[pid 882162] read(5,  <unfinished ...>
[pid 882161] write(1, "??\n??:0:0\n\n", 11 <unfinished ...>
[pid 882162] <... read resumed>"??\n??:0:0\n\n", 4096) = 11
[pid 882161] <... write resumed>)       = 11
[pid 882162] write(4, "0x4028d4\n", 9 <unfinished ...>
[pid 882161] read(0,  <unfinished ...>
[pid 882162] <... write resumed>)       = 9
[pid 882161] <... read resumed>"0x4028d4\n", 4096) = 9
[pid 882162] read(5,  <unfinished ...>
[pid 882161] write(1, "_start\n??:0:0\n\n", 15 <unfinished ...>
[pid 882162] <... read resumed>"_start\n??:0:0\n\n", 4096) = 15
[pid 882161] <... write resumed>)       = 15
[pid 882162] mprotect(0x7ffff02fd000, 49152, PROT_READ|PROT_WRITE <unfinished ...>
[pid 882161] read(0,  <unfinished ...>
[pid 882162] <... mprotect resumed>)    = 0
[pid 882162] futex(0x7ffff7dbc450, FUTEX_WAKE, 1) = 1
[pid 882162] futex(0x7ffff7dbc470, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, 0, NULL, FUTEX_BITSET_MATCH_ANY <unfinished ...>
[pid 882164] <... futex resumed>)       = 0
[pid 882164] futex(0x7ffff7aeb470, FUTEX_WAKE, 1) = 1
[pid 882162] <... futex resumed>)       = 0
[pid 882164] futex(0x7ffff7aeb450, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, 0, NULL, FUTEX_BITSET_MATCH_ANY <unfinished ...>
[pid 882162] futex(0x7ffff7dbc450, FUTEX_WAKE, 1 <unfinished ...>
[pid 882164] <... futex resumed>)       = -1 EAGAIN (Resource temporarily unavailable)
[pid 882162] <... futex resumed>)       = 0
[pid 882164] futex(0x7ffff7aeb450, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, 0, NULL, FUTEX_BITSET_MATCH_ANY <unfinished ...>
[pid 882162] futex(0x7ffff7dbc450, FUTEX_WAKE, 1 <unfinished ...>
[pid 882164] <... futex resumed>)       = -1 EAGAIN (Resource temporarily unavailable)
[pid 882162] <... futex resumed>)       = 0
[pid 882164] recvmsg(6,  <unfinished ...>
[pid 882162] futex(0x7ffff7dbc470, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, 0, NULL, FUTEX_BITSET_MATCH_ANY

@jukefr
Copy link
Author

jukefr commented Dec 11, 2024

i added a bunch of logs until i found where it got stuck and it appears its here specifically https://github.com/froz42/funcheck/blob/main/host/srcs/run/runner.c#L178

@froz42
Copy link
Owner

froz42 commented Dec 11, 2024

Hello, thank for your issue, did you tried the pre-compiled version of funcheck ? I do not think this is related to nix flake

@froz42 froz42 self-assigned this Dec 11, 2024
@jukefr
Copy link
Author

jukefr commented Dec 11, 2024

I can't really run prebuilt dynamically linked executables "easily" :( https://nix.dev/guides/faq#how-to-run-non-nix-executables
I have to patch the elf for it to work
But at least the prebuilt version got further and actually "runs" (but very slow and the x11 window is just a black screen)
I'm not really sure its working but compared to the nix build at least it doesn't hang and opens the X window...
image

@jukefr
Copy link
Author

jukefr commented Dec 13, 2024

ok so after alot of pain i am trying to find the issue...

i added some logs in the mlx hooks...

 INFO  Running program details:
 INFO    Program: ./result/bin/so_long
 INFO    Arguments:
 INFO      maps/map1.ber
 INFO  Forking process to run program
 INFO  Parent process continuing (child pid: 286059)
 INFO  Initial child process state: R (running)

 INFO  Child process started (pid: 286059)
 INFO  X11 Display: :0
 INFO  XAUTHORITY: not set
 INFO  Checking X11 socket: /tmp/.X11-unix/X0
 INFO  X11 socket exists
 INFO  X11 socket permissions: 755
 INFO  X11 socket exists and is owned by uid: 1000
 INFO  Executing program with execvpe
DEBUG: X11 hooks initialized
DEBUG: XSync hook at: 0x7f59096dcbd0
DEBUG: Library constructor called
DEBUG: setup() called
DEBUG: disabled hooks
DEBUG: initialized shared memory
DEBUG: Signals set up
DEBUG: Exit hook set up
DEBUG: setup hooks
DEBUG: setup() complete
DEBUG: XCreateGC hook called with display: 0x1a10b7b0
DEBUG: XCreateGC original function address: 0x7f590954e270
 INFO  Child process state after 100ms: S (sleeping)

 INFO  Child process state after 1s: S (sleeping)

i also have debug logs in xsync but for some reason they do not appear...

int EXPORT XSync(Display *a, Bool b)
{
    if (getenv("DEBUG"))
        fprintf(stderr, "DEBUG: XSync hook called\n");
    (void)a;
    (void)b;
    exit(0);
    return 0;
}

ltrace shows that the program does call Xsync....

ltrace -e 'X*' ./result/bin/so_long maps/map1.ber              [±master ●(✹)]
so_long->XOpenDisplay(0x4081a8, 0, 0, 0 <unfinished ...>
libX11.so.6->XSetErrorHandler(0, 0, 0, 0xffffff80) = 0x7f8a49160680
libX11.so.6->XSetIOErrorHandler(0, 0, 0, 0)       = 0x7f8a49160590
libxcb.so.1->XauGetBestAuthByAddr(256, 10, 0x7ffca9a500c0, 1 <unfinished ...>
libXau.so.6->XauFileName(256, 10, 0x7ffca9a500c0, 1) = 0x21e717c0
<... XauGetBestAuthByAddr resumed> )              = 0
libX11.so.6->XCreateGC(0x21e703c0, 892, 12, 0x7ffca9a503f0) = 0x21e819e0
libX11.so.6->XSynchronize(0x21e703c0, 0, 0, 0)    = 0
libX11.so.6->XkbUseExtension(0x21e703c0, 0, 0, 0 <unfinished ...>
libX11.so.6->XInitExtension(0x21e703c0, 0x7f8a491c76cf, 0, 68 <unfinished ...>
libX11.so.6->XQueryExtension(0x21e703c0, 0x7f8a491c76cf, 0x7ffca9a50304, 0x7ffca9a50308) = 1
<... XInitExtension resumed> )                    = 0x21e81b78
libX11.so.6->XESetWireToEvent(0x21e703c0, 85, 0x7f8a491b7450, 0) = 0x7f8a4915ff40
<... XkbUseExtension resumed> )                   = 1
<... XOpenDisplay resumed> )                      = 0x21e703c0
so_long->XInternAtom(0x21e703c0, 0x408207, 0, 0)  = 321
so_long->XInternAtom(0x21e703c0, 0x408218, 0, 0)  = 313
so_long->XShmQueryVersion(0x21e703c0, 0x7ffca9a5046c, 0x7ffca9a5046c, 0x7ffca9a50468 <unfinished ...>
libXext.so.6->XextFindDisplay(0x7f8a49115820, 0x21e703c0, 0x7ffca9a5046c, 0x7ffca9a50468) = 0
libXext.so.6->XextAddDisplay(0x7f8a49115820, 0x21e703c0, 0x7f8a491100ba, 0x7f8a491154a0 <unfinished ...>
libXext.so.6->XInitExtension(0x21e703c0, 0x7f8a491100ba, 0, 0 <unfinished ...>
libX11.so.6->XQueryExtension(0x21e703c0, 0x7f8a491100ba, 0x7ffca9a50364, 0x7ffca9a50368) = 1
<... XInitExtension resumed> )                    = 0x21e81e98
libXext.so.6->XESetWireToEvent(0x21e703c0, 65, 0x7f8a4910a5e0, 0) = 0x7f8a4915ff40
libXext.so.6->XESetEventToWire(0x21e703c0, 65, 0x7f8a4910a530, 0) = 0x7f8a4915ff70
libXext.so.6->XextCreateExtension(0, 130, 0x7f8a491154a0, 71) = 0x21e81a90
libXext.so.6->XextFindDisplay(0x21e81a90, 0x21e703c0, 0, 0) = 0
libXext.so.6->XextAddDisplay(0x21e81a90, 0x21e703c0, 0x7f8a49110200, 0x7f8a49115660 <unfinished ...>
libXext.so.6->XInitExtension(0x21e703c0, 0x7f8a49110200, 0, 0 <unfinished ...>
libX11.so.6->XQueryExtension(0x21e703c0, 0x7f8a49110200, 0x7ffca9a502b4, 0x7ffca9a502b8) = 1
<... XInitExtension resumed> )                    = 0x21e81f98
libXext.so.6->XESetCloseDisplay(0x21e703c0, 2, 0x7f8a4910f060, 0) = 0
<... XextAddDisplay resumed> )                    = 0x21e81e60
libXext.so.6->XESetWireToEvent(0x21e703c0, 35, 0x7f8a4910eff0, 0) = 0x7f8a4915ff80
libXext.so.6->XESetEventToWire(0x21e703c0, 35, 0x7f8a4910ef70, 0) = 0
libXext.so.6->XESetCloseDisplay(0x21e703c0, 1, 0x7f8a4910a480, 0) = 0
libXext.so.6->XESetErrorString(0x21e703c0, 1, 0x7f8a4910a6a0, 0) = 0
<... XextAddDisplay resumed> )                    = 0x21e81e30
<... XShmQueryVersion resumed> )                  = 1
so_long->XShmPixmapFormat(0x21e703c0, 0, 0xffffffff, 0 <unfinished ...>
libXext.so.6->XextFindDisplay(0x7f8a49115820, 0x21e703c0, 0xffffffff, 0) = 0x21e81e30
<... XShmPixmapFormat resumed> )                  = 2
so_long->XCreateWindow(0x21e703c0, 892, 0, 0)     = 0x1c00001
so_long->XGetWMNormalHints(0x21e703c0, 0x1c00001, 0x7ffca9a50320, 0x7ffca9a50318 <unfinished ...>
libX11.so.6->XGetWMSizeHints(0x21e703c0, 0x1c00001, 0x7ffca9a50320, 0x7ffca9a50318 <unfinished ...>
libX11.so.6->XGetWindowProperty(0x21e703c0, 0x1c00001, 40, 0) = 0
<... XGetWMSizeHints resumed> )                   = 0
<... XGetWMNormalHints resumed> )                 = 0
so_long->XSetWMNormalHints(0x21e703c0, 0x1c00001, 0x7ffca9a50320, 0 <unfinished ...>
libX11.so.6->XSetWMSizeHints(0x21e703c0, 0x1c00001, 0x7ffca9a50320, 40 <unfinished ...>
libX11.so.6->XChangeProperty(0x21e703c0, 0x1c00001, 40, 41) = 1
<... XSetWMSizeHints resumed> )                   = 0
<... XSetWMNormalHints resumed> )                 = 0
so_long->XStoreName(0x21e703c0, 0x1c00001, 0x4080d0, 0 <unfinished ...>
libX11.so.6->XChangeProperty(0x21e703c0, 0x1c00001, 39, 31) = 1
<... XStoreName resumed> )                        = 1
so_long->XSetWMProtocols(0x21e703c0, 0x1c00001, 0x21e703a0, 1 <unfinished ...>
libX11.so.6->XChangeProperty(0x21e703c0, 0x1c00001, 313, 4) = 1
<... XSetWMProtocols resumed> )                   = 1
so_long->XCreateGC(0x21e703c0, 0x1c00001, 7, 0x7ffca9a50410) = 0x21e82ba0
so_long->XMapRaised(0x21e703c0, 0x1c00001, 0x21e82838, 0) = 1
so_long->XWindowEvent(0x21e703c0, 0x1c00001, 0x8000, 0x7ffca9a502b0) = 0
so_long->XPutBackEvent(0x21e703c0, 0x7ffca9a502b0, 0, 0) = 0
^[so_long->XShmCreateImage(0x21e703c0, 0x21e7cf60, 24, 2) = 0x21e83250
so_long->XSetErrorHandler(0x4060a0, 0, 0, 0)      = 0x7f8a49160680
so_long->XShmAttach(0x21e703c0, 0x21e83228, 0, 0 <unfinished ...>
libXext.so.6->XextFindDisplay(0x7f8a49115820, 0x21e703c0, 0, 0) = 0x21e81e30
<... XShmAttach resumed> )                        = 1
so_long->XSync(0x21e703c0, 0, 0, 0)               = 1
[...]

but yeah the we seem to never get into the xsync hook...

edit:
added a hook for xsyncrhonize which comes right after xcreategc

int (*EXPORT XSynchronize(Display *display, Bool onoff))()
{
	printf("DEBUG: XSynchronize called with display=%p, onoff=%d\n", (void*)display, onoff);
	disable_alloc_hooks();
	typeof(&XSynchronize) original_function = get_original_function();
	int (*result)() = original_function(display, onoff);
	enable_alloc_hooks();
	return result;
}

and i dont see the log when i run funcheck

will update this post as i keep trying stuff...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants