I would strongly advise avoiding unix-signals from CGO. I've done it and 
can recommend against it (it needs very elaborate signal masking to avoid 
crashing the Go runtime); it was still very fraught and probably not 
supported :) 

Just catch C-side exceptions in C, turn them into strings, pass the string 
back to your Go stub, and send the string on a channel from Go to Go if you 
need to.

On Sunday, January 19, 2025 at 1:58:51 PM UTC Robert Engels wrote:

> After more reading, if you install the vectored exception handler it 
> should work as it can receive the exceptions outside its own stack frames. 
>
> On Jan 19, 2025, at 7:47 AM, Robert Engels <ren...@ix.netcom.com> wrote:
>
> 
>
> Read this section: Go handles the exceptions listed otherwise this is the 
> process:
>
> Raising an exception causes the exception dispatcher to go through the 
> following search for an exception handler:
>
>    1. The system first attempts to notify the process's debugger, if any.
>    2. If the process is not being debugged, or if the associated debugger 
>    does not handle the exception, the system attempts to locate a frame-based 
>    exception handler by searching the stack frames of the thread in which the 
>    exception occurred. The system searches the current stack frame first, 
> then 
>    proceeds backward through preceding stack frames.
>    3. If no frame-based handler can be found, or no frame-based handler 
>    handles the exception, the system makes a second attempt to notify the 
>    process's debugger.
>    4. If the process is not being debugged, or if the associated debugger 
>    does not handle the exception, the system provides default handling based 
>    on the exception type. For most exceptions, the default action is to call 
>    the ExitProcess 
>    
> <https://learn.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-exitprocess>
>     function.
>
>
>
>
> On Jan 19, 2025, at 7:45 AM, Robert Engels <ren...@ix.netcom.com> wrote:
>
> 
> You need to install a handler using CGO. When it is not a Go exception it 
> uses “continue” - eventually your handler will be called. You handle it in 
> the native Go and communicate the signal back to Go using a channel of some 
> other means. 
>
> A lot depends on what you are trying to do and why? Why not just use one 
> of the “user defined” signals instead of the special one you are trying to 
> use. Then you can use the standard signals package. 
>
> On Jan 19, 2025, at 7:03 AM, rudeus greyrat <rudeusqu...@gmail.com> wrote:
>
> 
> I investigated a little bit and got lost :p
>
> Basically I raise a windows exception with RaiseException windows API to 
> simulate my exception (
> https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-raiseexception
> )
>
>
> From what I understand, Go search the exception handler vector and because 
> it is not a go exception (See 
> https://github.com/golang/go/blob/40b3c0e58a0ae8dec4684a009bf3806769e0fc41/src/runtime/signal_windows.go#L310)
>  
> it _EXCEPTION_CONTINUE_SEARCH then it is going to winthrow (
> https://github.com/golang/go/blob/40b3c0e58a0ae8dec4684a009bf3806769e0fc41/src/runtime/signal_windows.go#L349C1-L349C5)
>  
> then printing the stack and exiting the program.
>
> I don't see how it can be translated to a go signal ...
>
> Le samedi 18 janvier 2025 à 20:20:27 UTC+1, robert engels a écrit :
>
>> Are you certain the exception isn’t already being translated to a signal?
>>
>> [image: go.png]
>>
>> go/src/syscall/types_windows.go at 
>> 40b3c0e58a0ae8dec4684a009bf3806769e0fc41 · golang/go 
>> <https://github.com/golang/go/blob/40b3c0e58a0ae8dec4684a009bf3806769e0fc41/src/syscall/types_windows.go#L54-L86>
>> github.com 
>> <https://github.com/golang/go/blob/40b3c0e58a0ae8dec4684a009bf3806769e0fc41/src/syscall/types_windows.go#L54-L86>
>>
>> <https://github.com/golang/go/blob/40b3c0e58a0ae8dec4684a009bf3806769e0fc41/src/syscall/types_windows.go#L54-L86>
>>
>>
>> On Jan 18, 2025, at 12:46 PM, rudeus greyrat <rudeusqu...@gmail.com> 
>> wrote:
>>
>> I will try to do that later in CGO !!
>>
>> If I remember correctly (tell me if I am wrong) The thing is I noticed 
>> when I compile with CGO the binary is much bigger ... So I avoid using CGO 
>> whenever it is possible and always try to rely on go assembler and go :)
>>
>> Le samedi 18 janvier 2025 à 19:28:13 UTC+1, robert engels a écrit :
>>
>>> Rather than modifying the Go runtime, why not install the exception 
>>> handler using CGO, and then report back to go and fire the signal there 
>>> using the signals package?
>>>
>>> Although reading the signals package, https://pkg.go.dev/os/signal I 
>>> would expect that this exception - since it is unrelated to running Go code 
>>> - should be reported as one of the other OS signals.
>>>
>>> On Jan 18, 2025, at 12:10 PM, rudeus greyrat <rudeusqu...@gmail.com> 
>>> wrote:
>>>
>>> Thanks for answering. Basically I found a work around. 
>>>
>>> As I said, I understand go handles error differently, but imagine my 
>>> windows OS send an exception signal not handled by go, how to handle this ? 
>>> Escpecially given I don;'t just want the default Go handler that print the 
>>> stack with the exception code and registers then exit the program ...
>>>
>>> By default, in the Go runtime you indeed use the 
>>> AddVectoredExceptionHandler windows API (which is why it is imported by 
>>> Kernel32.dll in the Import Address Table and linked to the Go binary).
>>>
>>> However you use just a set of exception and not everything :D
>>>
>>> Correct me If I am wrong but from what I saw in `signal_windows.go`:
>>> ```
>>> case _EXCEPTION_ACCESS_VIOLATION:
>>> case _EXCEPTION_IN_PAGE_ERROR:
>>> case _EXCEPTION_INT_DIVIDE_BY_ZERO:
>>> case _EXCEPTION_INT_OVERFLOW:
>>> case _EXCEPTION_FLT_DENORMAL_OPERAND:
>>> case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
>>> case _EXCEPTION_FLT_INEXACT_RESULT:
>>> case _EXCEPTION_FLT_OVERFLOW:
>>> case _EXCEPTION_FLT_UNDERFLOW:
>>> case _EXCEPTION_BREAKPOINT:
>>> case _EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on 
>>> arm64
>>> ```
>>>
>>> You only treat these exceptions in `isgoexception` function. 
>>>
>>> I changed `isgoexception` to:
>>>
>>> ```
>>> func isgoexception(info *exceptionrecord, r *context) bool {
>>> switch info.exceptioncode {
>>> default:
>>> return false
>>> case _EXCEPTION_ACCESS_VIOLATION:
>>> case _EXCEPTION_IN_PAGE_ERROR:
>>> case _EXCEPTION_INT_DIVIDE_BY_ZERO:
>>> case _EXCEPTION_INT_OVERFLOW:
>>> case _EXCEPTION_FLT_DENORMAL_OPERAND:
>>> case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
>>> case _EXCEPTION_FLT_INEXACT_RESULT:
>>> case _EXCEPTION_FLT_OVERFLOW:
>>> case _EXCEPTION_FLT_UNDERFLOW:
>>> case _EXCEPTION_BREAKPOINT:
>>>         case 
>>> 0xE0000001:                                                       // HERE I 
>>> added this and changed order 
>>> case _EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on 
>>> arm64
>>> }
>>> return true
>>>
>>> if r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip() {
>>>                 println("In Weird Stuff")
>>> return false
>>> }
>>>
>>>     return true
>>> }
>>> ```
>>>
>>> And basically I can now handle my Exception Signal.
>>>
>>> ```
>>> func myHandler(exceptionInfo *handler.EXCEPTION_POINTERS) uintptr {
>>> println("Exception occurred! ---> Code")
>>> println(exceptionInfo.ExceptionRecord.ExceptionCode)
>>> println("Life happens, lets continue")
>>> // kernel32 := windows.NewLazySystemDLL("kernel32.dll")
>>> // exitt := kernel32.NewProc("ExitThread")
>>> // exitt.Call(uintptr(0))
>>> return uintptr(handler.EXCEPTION_CONTINUE_EXECUTION)
>>> }
>>>
>>> func main() {
>>> handler.AddVEH(myHandler)
>>>
>>>
>>>         raiseCustomException()
>>>
>>>
>>> println("Continued")
>>> }
>>> ```
>>>
>>> I get what I want when I run the exe:
>>>
>>> ```
>>> Added VEH
>>> Exception occurred! ---> Code
>>>        3758096385
>>> Life happens, lets continue
>>> Continued
>>> ```
>>>
>>> I still not fully understand how you handle AddVectoredExceptionHandler 
>>> in the go runtime and why Go decided not to let the user handle their 
>>> signal ... (as you see it seems easy, escepcially when the signal is 
>>> exterior to the go runtime)
>>>
>>> I might add this to my evil-go fork :p 
>>> https://github.com/almounah/evil-go
>>>
>>> PS: Don't take this the wrong way, but I hope *"Generative AI is 
>>> experimental"  *will stay experimental ...
>>>
>>>
>>>
>>>
>>> Le samedi 18 janvier 2025 à 15:15:57 UTC+1, Robert Engels a écrit :
>>>
>>>> You may also want to look into ago “signal handling” as a potential 
>>>> solution. 
>>>>
>>>> On Jan 18, 2025, at 8:06 AM, Robert Engels <ren...@ix.netcom.com> 
>>>> wrote:
>>>>
>>>> 
>>>>
>>>> If that wasn’t clear. It doesn’t seem to be supported. You need to 
>>>> catch the exception in the native code and return an error code back to 
>>>> Go. 
>>>>
>>>> On Jan 18, 2025, at 7:32 AM, Robert Engels <ren...@ix.netcom.com> 
>>>> wrote:
>>>>
>>>> 
>>>> Go and C handle errors differently: 
>>>>
>>>>    - Go: Go uses error values returned from functions to handle 
>>>>    errors. This approach makes error handling explicit and encourages 
>>>>    developers to handle them gracefully. 
>>>>    - C: C often uses exceptions and signals to handle errors. However, 
>>>>    C's error handling mechanisms don't directly translate to Go's error 
>>>>    handling approach. 
>>>>
>>>> Handling Errors in CGO: 
>>>>
>>>>    - Return Values: Many C functions return error codes or status 
>>>>    values. You can check these values in your Go code and handle them 
>>>>    accordingly. 
>>>>    - errno: C often sets the global variable errno to indicate an 
>>>>    error. You can access errno in Go using syscall.Errno. 
>>>>    - C++ Exceptions: C++ exceptions are not directly supported by 
>>>>    CGO. If your C++ code throws exceptions, you can wrap the code in a C 
>>>>    function that catches the exceptions and returns an error code. 
>>>>
>>>> Example: 
>>>>
>>>> package main
>>>>
>>>> /*
>>>> #include <stdio.h>
>>>> #include <stdlib.h>
>>>>
>>>> int divide(int a, int b, int *result) {
>>>>     if (b == 0) {
>>>>         return -1; // Error: division by zero
>>>>     }
>>>>     *result = a / b;
>>>>     return 0; // Success
>>>> }
>>>> */
>>>> import "C"
>>>> import (
>>>>    "fmt"
>>>>    "syscall"
>>>> )
>>>>
>>>> func main() {
>>>>    var result C.int
>>>>    ret := C.divide(10, 0, &result)
>>>>    if ret != 0 {
>>>>            if ret == -1 {
>>>>                    fmt.Println("Error: division by zero")
>>>>            } else {
>>>>                    fmt.Println("Error:", syscall.Errno(-ret))
>>>>            }
>>>>    } else {
>>>>            fmt.Println("Result:", int(result))
>>>>    }
>>>> }
>>>>
>>>>
>>>> Important Considerations: 
>>>>
>>>>    - Error Handling Consistency: Strive to maintain consistent error 
>>>>    handling across your Go and C code. 
>>>>    - Panic: Avoid panicking in CGO code. Instead, return error values 
>>>>    to your Go code to handle them gracefully. 
>>>>    - Memory Management: Be mindful of memory allocation and 
>>>>    deallocation when working with CGO. 
>>>>
>>>> Alternatives to CGO: 
>>>>
>>>>    - Go Wrappers: If possible, consider writing pure Go wrappers 
>>>>    around C libraries to provide a more idiomatic Go interface. 
>>>>    - RPC: For more complex interactions, consider using RPC mechanisms 
>>>>    like gRPC to communicate between Go and C components. 
>>>>
>>>>
>>>> *Generative AI is experimental.*
>>>>
>>>> On Jan 18, 2025, at 7:21 AM, rudeus greyrat <rudeusqu...@gmail.com> 
>>>> wrote:
>>>>
>>>> 
>>>> The issue seems to come from firstcontinuehandler, I tweaked it a 
>>>> little and it is getting better
>>>>
>>>> ```
>>>> // It seems Windows searches ContinueHandler's list even
>>>> // if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
>>>> // firstcontinuehandler will stop that search,
>>>> // if exceptionhandler did the same earlier.
>>>> //
>>>> // It is nosplit for the same reason as exceptionhandler.
>>>> //
>>>> //go:nosplit
>>>> func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) 
>>>> int32 {
>>>>     print("Went in first Continue Handler")
>>>> if !isgoexception(info, r) {
>>>>         println("It is not go exception")
>>>> return _EXCEPTION_CONTINUE_SEARCH
>>>> }
>>>>     println("It is a go exception")
>>>> return _EXCEPTION_CONTINUE_EXECUTION
>>>> }
>>>> ```
>>>>
>>>> Seems go is not allowing "non Go exception" to be handled by Go code
>>>> Le samedi 18 janvier 2025 à 12:51:12 UTC+1, rudeus greyrat a écrit :
>>>>
>>>>> Any idea please ? Been stuck at this for quite some time, seems that 
>>>>> Go is neglecting the return uintptr(handler.EXCEPTION_CONTINUE_SEARCH) 
>>>>> and 
>>>>> going into panic mode ...
>>>>>
>>>>>
>>>>> Le vendredi 17 janvier 2025 à 16:30:24 UTC+1, rudeus greyrat a écrit :
>>>>>
>>>>>>
>>>>>> https://stackoverflow.com/questions/79365198/cannot-continue-after-entering-vectored-exception-handler-in-go
>>>>>>
>>>>>> asked the question here too if people want to have syntax highlight
>>>>>>
>>>>>> Le vendredi 17 janvier 2025 à 14:16:30 UTC+1, rudeus greyrat a écrit :
>>>>>>
>>>>>>> PS: I know there is defer recover mechanism in Go that can be used 
>>>>>>> to handle exception... But I would like to use 
>>>>>>> AddVectoredExceptionHandler 
>>>>>>> (maybe it is already used behind the scene with defer recover ?) 
>>>>>>> because I 
>>>>>>> can inspect the thread context in myhandler function
>>>>>>>
>>>>>>> Le vendredi 17 janvier 2025 à 13:17:07 UTC+1, rudeus greyrat a 
>>>>>>> écrit :
>>>>>>>
>>>>>>>> I want to be able to catch windows exception and do stuff with it 
>>>>>>>> (mainly for hardware break point later).
>>>>>>>>
>>>>>>>> I created a custom function to add a Vectored Exception Handler 
>>>>>>>> using the windows API call AddVectoredExceptionHandler:
>>>>>>>> ```
>>>>>>>> func AddVEH(myHandler PVECTORED_EXCEPTION_HANDLER) error {
>>>>>>>>     kernel32 := syscall.NewLazyDLL("kernel32.dll")
>>>>>>>> addVectoredExceptionHandler := 
>>>>>>>> kernel32.NewProc("AddVectoredExceptionHandler")
>>>>>>>>
>>>>>>>>     
>>>>>>>> _, _, err := addVectoredExceptionHandler.Call(
>>>>>>>> uintptr(1),
>>>>>>>> syscall.NewCallback(func(exceptionInfo *EXCEPTION_POINTERS) uintptr 
>>>>>>>> {
>>>>>>>> return myHandler(exceptionInfo)
>>>>>>>> }),
>>>>>>>> )
>>>>>>>>     if err != nil {
>>>>>>>>         fmt.Println("Error Setting the VEH")
>>>>>>>>         fmt.Println(err.Error())
>>>>>>>>     }
>>>>>>>>     return err
>>>>>>>> }
>>>>>>>> ```
>>>>>>>>
>>>>>>>> I test it with a custom exception I raise:
>>>>>>>> ```
>>>>>>>> func myHandler(exceptionInfo *handler.EXCEPTION_POINTERS) uintptr {
>>>>>>>> println("Exception occurred! ---> Code")
>>>>>>>> println(exceptionInfo.ExceptionRecord.ExceptionCode)
>>>>>>>> println("It happends in life, lets continue")
>>>>>>>> return ^uintptr(0) // EXCEPTION_CONTINUE_EXECUTION = -1
>>>>>>>> }
>>>>>>>>
>>>>>>>> func main() {
>>>>>>>> handler.AddVEH(myHandler)
>>>>>>>>
>>>>>>>> raiseCustomException() // Just Raises a custom EXCEPTION with 
>>>>>>>> RaiseException winapi and code 0xE0000001
>>>>>>>>
>>>>>>>> println("Continued")
>>>>>>>> }
>>>>>>>> ```
>>>>>>>>
>>>>>>>> As I return with EXCEPTION_CONTINUE_EXECUTION, I expect that 
>>>>>>>> `println("Continued")` will be executed. However, it is not the case 
>>>>>>>> at all:
>>>>>>>> ```
>>>>>>>> Error Setting the VEH
>>>>>>>>     The operation completed successfully.
>>>>>>>> Exception occurred! ---> Code
>>>>>>>> 3758096385
>>>>>>>> It happends in life, lets continue
>>>>>>>> Exception 0xe0000001 0x7eb71d5fb17c 0x1b 0x7ffc54e4b699
>>>>>>>> PC=0x7ffc54e4b699
>>>>>>>>
>>>>>>>> runtime.cgocall(0xf1dde0, 0xc000049b30)
>>>>>>>>         runtime/cgocall.go:167 +0x3e fp=0xc00006fe28 
>>>>>>>> sp=0xc00006fdc0 pc=0xf10a7e
>>>>>>>> syscall.SyscallN(0xc00001e410?, {0xc0000121c0?, 0x0?, 0xf39a00?})
>>>>>>>> ```
>>>>>>>>
>>>>>>>> As you see the program enter the handler function but never 
>>>>>>>> continues, rather it exit and print the stack trace... 
>>>>>>>>
>>>>>>>> Not sure if it is because of syscall.NewCallback or something else 
>>>>>>>> ...
>>>>>>>>
>>>>>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "golang-nuts" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to golang-nuts...@googlegroups.com.
>>>> To view this discussion visit 
>>>> https://groups.google.com/d/msgid/golang-nuts/59818114-e21a-4b34-9f48-f6ff6e257c0fn%40googlegroups.com
>>>>  
>>>> <https://groups.google.com/d/msgid/golang-nuts/59818114-e21a-4b34-9f48-f6ff6e257c0fn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "golang-nuts" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to golang-nuts...@googlegroups.com.
>>>> To view this discussion visit 
>>>> https://groups.google.com/d/msgid/golang-nuts/35174CC7-0301-4891-8D8F-EC3735AECA5A%40ix.netcom.com
>>>>  
>>>> <https://groups.google.com/d/msgid/golang-nuts/35174CC7-0301-4891-8D8F-EC3735AECA5A%40ix.netcom.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "golang-nuts" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to golang-nuts...@googlegroups.com.
>>>>
>>>> To view this discussion visit 
>>>> https://groups.google.com/d/msgid/golang-nuts/237A6F4C-29A1-423D-83B5-C4590C221424%40ix.netcom.com
>>>>  
>>>> <https://groups.google.com/d/msgid/golang-nuts/237A6F4C-29A1-423D-83B5-C4590C221424%40ix.netcom.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to golang-nuts...@googlegroups.com.
>>>
>>> To view this discussion visit 
>>> https://groups.google.com/d/msgid/golang-nuts/d4bf1715-d073-49b6-ab67-27240a276f15n%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/d4bf1715-d073-49b6-ab67-27240a276f15n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>>
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>>
>> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/507bfa72-5586-4030-9b5f-d71998169da2n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/507bfa72-5586-4030-9b5f-d71998169da2n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>>
>> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com.
> To view this discussion visit 
> https://groups.google.com/d/msgid/golang-nuts/81184ca4-8a10-4457-a366-ae01c45f8ce3n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/81184ca4-8a10-4457-a366-ae01c45f8ce3n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com.
> To view this discussion visit 
> https://groups.google.com/d/msgid/golang-nuts/20874169-5C6E-4947-978C-9E627CF3BA7A%40ix.netcom.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/20874169-5C6E-4947-978C-9E627CF3BA7A%40ix.netcom.com?utm_medium=email&utm_source=footer>
> .
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com.
>
> To view this discussion visit 
> https://groups.google.com/d/msgid/golang-nuts/8621A752-464F-465C-A7E1-003D05360939%40ix.netcom.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/8621A752-464F-465C-A7E1-003D05360939%40ix.netcom.com?utm_medium=email&utm_source=footer>
> .
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/e7d063e4-33fe-4379-afe1-bef775a2e38dn%40googlegroups.com.

Reply via email to