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.