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+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/81184ca4-8a10-4457-a366-ae01c45f8ce3n%40googlegroups.com.

Reply via email to