Hi Sage - 

Does your SIGSEGV MAPERR show up only while attached to a debugger?
If so I noticed similar behavior while debugging my own project this week, 
and opened #2882 <https://github.com/racket/racket/issues/2882>.
It took me quite a bit of head scratching before I realized that (a) it 
only manifests as an immediate crash when the process is attached to a 
debugging tool, and (b) it happens even if I don't try to run any of my own 
code.

Let me know if this is helpful.

On Wednesday, October 30, 2019 at 4:57:08 PM UTC-4, Sage Gerard wrote:
>
> Hi Matthew, 
>
> I reproduced "SIGSEGV MAPERR si_code 1 fault on addr (nil)" after 
> specifying '#:atomic? #t', so not out of the woods yet. 
>
> If you wish I can help you set up Vulkan off-list. 
>
> > Will the callback definitely be invoked in the same OS-level thread as 
> calls to Vulkan functions? 
>
> Yes. [1] 
>
> Even so, I specified #:async-apply for grins. No change in behavior. 
>
> The only new development I can share is that the program now functions 
> correctly, provided that if I comment out the expression that tries to 
> register the callback. Previously the program was not even finished, so I 
> can at least say the problem is isolated. 
>
> I tried setting PLTSTDOUT to "debug" and prepared a diff between the 
> output when I try to use the callback, and the output when I don't try at 
> all. Sadly, when the program breaks the last line from STDOUT is 'ffi-lib: 
> loaded "libvulkan.so"'. 
>
> I'll wait for one more round of advice on troubleshooting before writing a 
> repository that reproduces the problem with added logging in a C shim. 
>
> [1]: 
> https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VkDebugReportCallbackCreateInfoEXT,
>  
> "A callback will always be executed in the same thread as the originating 
> Vulkan call." 
>
>
> ~slg 
>
> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ 
> On Tuesday, October 29, 2019 9:35 AM, Matthew Flatt <mfl...@cs.utah.edu 
> <javascript:>> wrote: 
>
> > I haven't been able to get Vulkan going on my machines, so I can't run 
> > your code enough to offer reliable advice. 
> > 
> > Still, I wonder whether making the callback atomic has any effect. 
> > To make the callback atomic: 
> > 
> > -   Change the definition of `_PFN_vkDebugReportCallbackEXT` to add 
> >     `#:atomic? #t` after `_fun`. 
> > 
> > -   Don't use `printf` in the callback, because that's not safe from 
> >     atomic code. Instead, use logging, which is ok to use from atomic 
> >     code. 
> > 
> >     "Atomic" means atomic with respect to the Racket runtime system, so 
> >     Racket won't try to swap its threads while running the callback. 
> >     Swapping threads involves coping the C stack, which often annoys 
> C/C++ 
> >     libraries. 
> > 
> >     Will the callback definitely be invoked in the same OS-level thread 
> as 
> >     calls to Vulkan functions? If not, then specify `#:async-apply 
> (lambda (thunk) (thunk))` alongside `#:atomic? #t` to make sure the 
> callback is 
> >     run in Racket's thread. 
> > 
> >     At Sun, 27 Oct 2019 19:57:52 +0000, Sage Gerard wrote: 
> > 
> > 
> > > I was still stumped on this one due to the opaque error message and 
> repeated 
> > > comparisons to the original source appearing correct. I stepped away 
> for a 
> > > while to think about it, and the only option I see to help me along is 
> to 
> > > write a shared library in C that behaves similarly, and have it log 
> noisily to 
> > > STDOUT whatever it gets from a Racket program. 
> > > Since writing this shim would be tedious, are there any additional 
> > > troubleshooting techniques or tools unique to Racket that can help me 
> narrow 
> > > down the root cause of a crash in foreign code? 
> > > -------- Original Message -------- 
> > > On Oct 25, 2019, 1:56 AM, Sage Gerard wrote: 
> > > 
> > > > Hi Ryan, and thank you for the detailed and informative reply! 
> > > > I gathered that I should trust Racket's handling of values across 
> the 
> > > > foreign boundary more, 
> > > > and used what I learned from your email to get past one error. 
> Sadly, I 
> > > > landed on 
> > > > "SIGSEGV MAPERR si_code 1 fault on addr (nil)" right after, and 
> under a 
> > > > different context. 
> > > > The affected expression can be found at 1, and I verified that I do 
> not 
> > > > try to use a NULL pointer. 
> > > > This is a case where foreign function returns a "dummy" pointer to 
> another 
> > > > function whose 
> > > > signature the client is expected to know in advance, but the address 
> of the 
> > > > foreign 
> > > > function would NOT be known to get-ffi-obj since the procedure is 
> loaded 
> > > > dynamically 
> > > > by the library itself 2. 
> > > > The Vulkan docs call for casting this pointer to the function I 
> need. So if 
> > > > I'm understanding your email 
> > > > correctly, I need to prepare a value such that I produce a callout 
> object 
> > > > that knows the right signature. 
> > > > I tried using (cast) and (function-ptr), both of which failed with 
> different 
> > > > errors. The SIGSEGV error 
> > > > came from the (cast) case, which is visible in the source code now a 
> few 
> > > > lines above the linked line. 
> > > > (function-ptr) seemed to produce a callback and not a callout, so 
> it's still 
> > > > not useful: 
> > > > ; application: not a procedure; 
> > > > ; expected a procedure that can be applied to arguments 
> > > > ; given: #<ffi-callback> 
> > > > I understand your point about conversions automatically happening as 
> values 
> > > > pass 
> > > > across the FFI boundary. But if I can't specify the requested type 
> UNTIL a 
> > > > (cast) 
> > > > and I'm sure the destination signature is correct, then what do I 
> make of 
> > > > the SIGSEGV error? 
> > > 
> > > t#L260 
> > > 
> > > > 
> > > 
> > > anceProcAddr.html 
> > > 
> > > > ~slg 
> > > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ 
> > > > On Thursday, October 24, 2019 8:54 PM, Ryan Culpepper 
> ry...@ccs.neu.edu <javascript:> 
> > > > wrote: 
> > > > 
> > > > > On 10/25/19 12:45 AM, Sage Gerard wrote: 
> > > > > 
> > > > > > I am porting some C++ code to Racket that uses a function 
> pointer. 
> > > > > > C++ origin: See 294 through 306: 
> > > 
> > > 
> https://github.com/Erkaman/vulkan_minimal_compute/blob/master/src/main.cpp#L294
>  
> > > 
> > > > > > Racket destination: 
> > > 
> > > 
> https://github.com/zyrolasting/racket-vulkan/blob/master/examples/mandelbrot.rk
>  
> > > t#L240 
> > > 
> > > > > > How do I use function-ptr on debug-report-callback to produce a 
> valid 
> > > > > > function pointer matching this signature 
> > > 
> > > 
> https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/PFN_vkDeb
>  
> > > ugReportCallbackEXT.html? 
> > > 
> > > > > > My current error comes from line 250, on the expression 
> (function-ptr 
> > > > > > debug-report-callback _PFN_vkDebugReportCallbackEXT): 
> > > > > > ; function-ptr: contract violation 
> > > > > > ; expected: (and ctype? (lambda (ct) (eq? 'fpointer 
> (ctype->layout 
> > > > > > ct)))) 
> > > > 
> > > > > > ; given: #<ctype> 
> > > > > > It seems that my error was that _PFN_vkDebugReportCallbackEXT 
> was 
> > > > > > (_cpointer/null (_fun ...)), but I am not sure what should take 
> its place. 
> > > > > > 
> > > > > > -   If I substitute _fpointer for _PFN_vkDebugReportCallbackEXT, 
> I get 
> > > > > >     the "application; not a procedure" error. 
> > > > > > 
> > > > > > -   If I substitute the _fun form with the signature I want, 
> then I get 
> > > > > >     "#<ctype>->C: argument is not `#<ctype>' pointer" 
> > > > > > 
> > > > > > 
> > > > > > I suspect this has something to do with the /callout/ concept 
> from the 
> > > > > > manual, but I don't understand how it applies here. 
> > > > > 
> > > > > The use of _cpointer/null seems wrong: its first argument is 
> interpreted 
> > > > > as a tag, so that's the source of the last error you mentioned. 
> The 
> > > > > `_cpointer/null` is unnecessary anyway, so just delete it: 
> > > > > (define _PFN_vkDebugReportCallbackEXT (_fun ....)) 
> > > > > On line 250: I don't think you need to use function-ptr. The field 
> > > > > setter will automatically convert debug-report-callback (I assume 
> that's 
> > > > > a Racket procedure) into a callback function pointer. 
> > > > > A callout is a foreign function gets converted into a Racket 
> > > > > procedure; a callback is when a Racket procedure gets turned into 
> a 
> > > > > function pointer so it can be called from foreign code. Both are 
> > > > > described by _fun ctypes. 
> > > > > Here's a simpler example. Suppose you have the following C code: 
> > > > > /* demo.c / 
> > > > > / gcc -fpic -shared -o demo.so demo.c */ 
> > > > > int an_int_fun(int x) { 
> > > > > return x + 1; 
> > > > > } 
> > > > > typedef int (*int2int)(int); 
> > > > > int apply_to_twelve(int2int f) { 
> > > > > return (*f)(12); 
> > > > > } 
> > > > > struct two_funs { 
> > > > > int2int f; 
> > > > > int2int g; 
> > > > > }; 
> > > > > int apply_two_funs_and_sum(struct two_funs *tf, int arg) { 
> > > > > return (tf->f)(arg) + (tf->g)(arg); 
> > > > > } 
> > > > > Here Racket bindings for the foreign code: 
> > > > > (require ffi/unsafe ffi/unsafe/define) 
> > > > > (define-ffi-definer define-demo (ffi-lib "demo.so")) 
> > > > > (define _int2int (_fun _int -> _int)) 
> > > > > (define-demo an_int_fun _int2int) 
> > > > > (define-demo apply_to_twelve (_fun _int2int -> _int)) 
> > > > > (define-cstruct _two_funs 
> > > > > ([f _int2int] 
> > > > > [g _int2int])) 
> > > > > (define-demo apply_two_funs_and_sum 
> > > > > (_fun _two_funs-pointer _int -> _int)) 
> > > > > In that Racket program,`an_int_fun` is a callout: a Racket 
> procedure 
> > > > > that calls foreign code when applied. 
> > > > > (an_int_fun 5) ;; => 6 
> > > > > If you call`apply_to_twelve` with a Racket procedure, like this: 
> > > > > (apply_to_twelve add1) ;; => 13 
> > > > > then the FFI converts`add1` (a Racket procedure) into a function 
> > > > > pointer using the _fun type `_int2int`. Foreign code can use that 
> > > > > function pointer to call back into Racket. 
> > > > > Storing a function in a struct with _int2int fields does the same 
> > > > > automatic conversion. For example: 
> > > > > (define (f x) (expt x 2)) 
> > > > > (define (g x) (expt x 3)) 
> > > > > (define tf (make-two_funs #f #f)) 
> > > > > (set-two_funs-f! tf f) 
> > > > > (set-two_funs-g! tf g) 
> > > > > ;; or equivalently, (define tf (make-two_funs f g)) 
> > > > > (apply_two_funs_and_sum tf 3) ;; => 36 
> > > > > You can even fetch one of the function fields back and call it, 
> like this: 
> > > > > ((two_funs-f tf) 4) ;; => 16 
> > > > > IIUC, that creates a callout procedure that calls the callback 
> function 
> > > > > pointer that calls the original Racket procedure. 
> > > > > I gave `f` and `g` names so they wouldn't be collected, but in 
> general 
> > > > > you need to make sure a Racket procedure doesn't get collected 
> when 
> > > > > foreign code still has a callback for it. For example, the 
> following 
> > > > > code is likely to crash: because the callback function pointer 
> stored in 
> > > > > tf2->g refers to a Racket procedure that has probably been GC'd: 
> > > > > (define tf2 (make-two_funs f (lambda (x) (expt x 5)))) 
> > > > > (collect-garbage) 
> > > > > (apply_two_funs_and_sum tf 3) 
> > > > > See the #:keep argument of `_fun` for more information. 
> > > > > Ryan 
> > > > 
> > > > -- 
> > > > You received this message because you are subscribed to the Google 
> Groups 
> > > > "Racket Users" group. 
> > > > To unsubscribe from this group and stop receiving emails from it, 
> send an 
> > > > email to racket...@googlegroups.com <javascript:>. 
> > > > To view this discussion on the web visit 
> > > > 
> https://groups.google.com/d/msgid/racket-users/RvdA1FGCG0kqT-1KB-Qq-n4Qt2Lt1YAz
>  
> > > > 
> gXoehgftKArWboBX5O6ymp-FJYYhFdKaoXjbjRl5GolUqOkyq9rgRamUWRcyU-ws2Rs4uTg-eTE%3D%
>  
>
> > > > 40sagegerard.com. 
> > > 
> > > -- 
> > > You received this message because you are subscribed to the Google 
> Groups 
> > > "Racket Users" group. 
> > > To unsubscribe from this group and stop receiving emails from it, send 
> an 
> > > email to racket...@googlegroups.com <javascript:>. 
> > > To view this discussion on the web visit 
> > > 
> https://groups.google.com/d/msgid/racket-users/uph-IOkMK3lOVu2aqZ5o2AtuintdpcsZ
>  
> > > 
> nwdlEi1Ql8FZzlbOf7gjgqWWuVKfVefLoXeC9AfvfUgHovzgXpPUzTiM2HzSNCxf1U357UVqjB0%3D%
>  
>
> > > 40sagegerard.com. 
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/4d802270-6a0d-4552-851c-0feecfa17841%40googlegroups.com.

Reply via email to