On 05.09.2021 08:03, paul wrote: > Good day, > > I have an existing app which is written in Swift and runs on macOS 10.15. I > would like to provide users a way of customising the app (initially just > simple things like modifying keybindings for example, later hopefully more) > and as a keen Emacs user, i'm inspired by the idea of providing a > Schemey/Lispy interface for such extensions. Guile looks like it'd be great > for this. If i understand correctly, it'd be best if i could bundle the > Guile runtime as a static library with the app, and call out to it to > evaluate user-provided code. I haven't thought deeply about this interface > yet; i thought i'd get a proof-of-concept working first. I wonder if i might > humbly ask for some guidance on how to get it working, because after a couple > of days i seem to have failed. I'm no C/threads/low-level guru, so my > apologies if i'm doing something very dumb. > > I had some difficulty getting my app to compile against Guile, but i > eventually managed to link against a version of Guile installed with Homebrew > (guile: stable 3.0.7 (bottled)), however when trying to boot it up i seemed > to run into the same issue described by Jeffrey Walton [1]. My app would > boot, and as soon as it hit the Guile initialisation calls, it would error > with "allocating JIT code buffer failed: Permission denied, jit.c:5804: > fatal: assertion failed". While that person seems to imply the problem is > with Apple's M1 silicon, i'm actually running an older machine (2.9 GHz > Dual-Core Intel Core i5, macOS 11.5.2). I then managed to get further by > downloading the Guile release tarball version 3.0.7 and and building with > `./configure --enable-jit=no`; this got me a bit further, however it still > didn't work: i think it is because some assumption Guile has about the thread > it runs on, or when it's invoked, is violated.. but i'm unsure how to find > out. > > What i currently have, is this snippet. It's being called from Swift land, > in the `applicationDidFinishLaunching(_ aNotification: Notification)` > function. As far as i can tell, that _is_ the main thread. > > ``` > #include "libguile.h" > > static void* register_functions (void* data) > { > SCM test = scm_c_eval_string("(+ 3 5)"); > int foo = scm_to_int(test); > printf("foo = %d\n", foo); > > return NULL; > } > > void run_guile() { > printf("hello from C, before Guile\n"); > scm_init_guile(); > //scm_with_guile(®ister_functions, NULL); // i've tried only having > this line uncommented, too, but that also causes immediate crashes > //scm_shell(0, NULL); > } > ``` > > This compiles fine, and i see the "hello from C" line printed, but then it > crashes. The error seems to vary, here are some i've seen: > > 1. "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" at line 182 of pairs.h, > 2. "Pre-boot error; key: misc-error, args: ("%search-path" "path is not a > proper list: ~a" (("/usr/local/share/guile/3.0" > "/usr/local/share/guile/site/3.0" "/usr/local/share/guile/site" . #<program > 12503b140 124fc10fc>)) #f)", "Thread 1: signal SIGABRT", line 260 of throw.c > 3. "Thread 1: EXC_BAD_ACCESS (code=1, address=0x9)", at line 585 of > weak-set.c. > 4. I've also sometimes seen this one, > https://lists.gnu.org/archive/html/emacs-bug-tracker/2020-01/msg00365.html, > although perhaps that's indeed related to closed stdout. > > Because these errors are different all the time i guess it's some race > condition or threading issue? I wonder if someone knows an avenue i can > attempt to use to debug what's going on? 🙏 > > All the best, > paul > > 1. https://mail.gnu.org/archive/html/bug-guile/2021-03/msg00012.html >
Hi Paul, To narrow down the issue, I'd attempt a few things, in order: 1. Compile only the C code, adding a main() function, just to make sure the OS and the chosen Guile version and such are working fine with each other. 2. Compile pure Objective-C code, calling that run_guile() function firstly directly from the main() function in main.m of the Objective-C program, and commenting out the NSApplicationMain() call that would initialize Apple's application framework. 3. See if reactivating the NSApplicationMain() call causes problems. (It should be called *after* the Guile initialization.) 4. See if you can use Guile's C functions from -applicationDidFinishLaunching: e.g. by doing: scm_c_eval_string("(begin (display 'HelloWorld) (newline))") If that works, we now have an Objective-C + Guile application, and want to move to using Swift instead. This is where my Apple knowledge hits its limits because I never used Swift. :-) But I guess Swift should have something equivalent to the main() function of C and Objective-C, and calling Guile initialization from there might do the trick. If you hit a problem in step 3 or 4, then it could mean that Guile and Cocoa are somehow incompatible as they both want to apply some magic to the C program while initializing themselves. I wouldn't know how to approach that issue. -- Taylan