Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: make crashing more useful on Windows #20498

Open
bhiggins opened this issue May 25, 2017 · 19 comments
Open

runtime: make crashing more useful on Windows #20498

bhiggins opened this issue May 25, 2017 · 19 comments

Comments

@bhiggins
Copy link

@bhiggins bhiggins commented May 25, 2017

What did you do?

Triggered an access violation, crashing the program.

What did you expect to see?

We configured user-mode dumps and were hoping to get a dump (either a full dump or a minidump). See: https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx

What did you see instead?

No dump.

Two suggestions:

  1. In runtime/signal_windows.go, change lastcontinuehandler to return _EXCEPTION_CONTINUE_SEARCH if docrash is true (instead of calling crash and exit(2)-ing). This will allow Windows's crash handling to run instead of being suppressed.
  2. In runtime/signal_windows.go, change crash() to call RaiseException instead of being a no-op.

We can submit a PR if this is agreeable.

@bradfitz bradfitz added this to the Go1.10 milestone May 25, 2017
@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented May 25, 2017

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 25, 2017

Try setting the environment variable GOTRACEBACK to "crash".

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 25, 2017

I should mention that GOTRACEBACK is documented at https://golang.org/pkg/runtime/ .

@bhiggins
Copy link
Author

@bhiggins bhiggins commented May 25, 2017

@ianlancetaylor, thanks, I didn't know about GOTRACEBACK, but it doesn't help here as "crashes in an operating system-specific manner" for Windows is currently a no-op with a TODO comment. See runtime/signal_windows.go (and my second suggestion above):

func crash() {
	// TODO: This routine should do whatever is needed
	// to make the Windows program abort/crash as it
	// would if Go was not intercepting signals.
	// On Unix the routine would remove the custom signal
	// handler and then raise a signal (like SIGABRT).
	// Something like that should happen here.
	// It's okay to leave this empty for now: if crash returns
	// the ordinary exit-after-panic happens.
}
@ptdiscus
Copy link

@ptdiscus ptdiscus commented May 26, 2017

@ianlancetaylor
I believe calling a "crash" function in lastcontinuehandler would cause the exception context record in the dump to point to the crash function. Returning _EXCEPTION_CONTINUE_SEARCH should cause the exception context record to point to the original source of the exception.

@alexbrainman
Copy link
Member

@alexbrainman alexbrainman commented May 28, 2017

Two suggestions:

Sounds good to me.

We can submit a PR if this is agreeable.

That is agreeble from me, thank you.
We use this https://golang.org/doc/contribute.html procedure instead of Github PRs.

I didn't know about GOTRACEBACK

I did know about GOTRACEBACK, but I did not know about "crashes in an operating system-specific manner instead of exiting" if GOTRACEBACK=crash. So the "crashing" part is not implemented on Windows.

I believe calling a "crash" function in lastcontinuehandler would cause the exception context record in the dump to point to the crash function.

Correct.

Returning _EXCEPTION_CONTINUE_SEARCH should cause the exception context record to point to the original source of the exception.

Correct. And that is what @bhiggins is proposing to add.

I think we are all on the same page.

Alex

@rsc rsc modified the milestones: Go1.10, Go1.11 Nov 22, 2017
@usirsiwal
Copy link

@usirsiwal usirsiwal commented Mar 19, 2018

We have a go+C program on Windows. In absence of coredump, it is hard for us to root cause errors in the C code. Will really appreciate resolution of this issue.

@alexbrainman
Copy link
Member

@alexbrainman alexbrainman commented Mar 20, 2018

Will really appreciate resolution of this issue.

@usirsiwal try changing runtime yourself and see if it helps you. And if it works for you, submit it here to help others.

If you have problems, just ask for help here.

Alex

@usirsiwal
Copy link

@usirsiwal usirsiwal commented Mar 20, 2018

@alexbrainman I will try the runtime change and see if it works for us.

@usirsiwal
Copy link

@usirsiwal usirsiwal commented Mar 28, 2018

Hello,
We came up with the following solution. We had to conditionally remove disableWER to get the crashdump. We are not sure if that is the right thing to do. Please let us know if there is a better way of doing it.

Thanks,
Umesh

diff --git "a/C:\\go1.10.windows-amd64\\go\\src\\runtime\\signal_windows.go.orig" "b/C:\\go1.10.windows-amd64\\go\\src\\runtime\\signal_windows.go"
index 518aac3c4..939379ce4 100644
--- "a/C:\\go1.10.windows-amd64\\go\\src\\runtime\\signal_windows.go.orig"
+++ "b/C:\\go1.10.windows-amd64\\go\\src\\runtime\\signal_windows.go"
@@ -148,7 +148,7 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        }

        if docrash {
-               crash()
+               return _EXCEPTION_CONTINUE_SEARCH
        }

        exit(2)
@@ -228,6 +228,10 @@ func crash() {
        // Something like that should happen here.
        // It's okay to leave this empty for now: if crash returns
        // the ordinary exit-after-panic happens.
+       _, _, docrash := gotraceback()
+       if docrash {
+               raiseException(0xdead)
+       }
 }

 // gsignalStack is unused on Windows.

 
 
 diff --git "a/C:\\go1.10.windows-amd64\\go\\src\\runtime\\os_windows.go.orig" "b/C:\\go1.10.windows-amd64\\go\\src\\runtime\\os_windows.go"
index 7aeadd9ef..18acc4dcf 100644
--- "a/C:\\go1.10.windows-amd64\\go\\src\\runtime\\os_windows.go.orig"
+++ "b/C:\\go1.10.windows-amd64\\go\\src\\runtime\\os_windows.go"
@@ -80,6 +80,7 @@ var (
        _LoadLibraryA,
        _QueryPerformanceCounter,
        _QueryPerformanceFrequency,
+       _RaiseException,
        _ResumeThread,
        _SetConsoleCtrlHandler,
        _SetErrorMode,
@@ -302,7 +303,10 @@ func osinit() {

        useLoadLibraryEx = (_LoadLibraryExW != nil && _AddDllDirectory != nil)

-       disableWER()
+       _, _, docrash := gotraceback()
+       if docrash {
+               disableWER()
+       }

        externalthreadhandlerp = funcPC(externalthreadhandler)

@@ -445,6 +449,15 @@ func exit(code int32) {
        stdcall1(_ExitProcess, uintptr(code))
 }

+//go:nosplit
+func raiseException(code int32) {
+       stdcall4(_RaiseException,
+               uintptr(code),
+               0,
+               0,
+               0)
+}
+
 //go:nosplit
 func write(fd uintptr, buf unsafe.Pointer, n int32) int32 {
        const (
@zhaoya881010
Copy link

@zhaoya881010 zhaoya881010 commented Aug 28, 2019

@usirsiwal @bhiggins i use https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx and try modify runtime according to the above.
go call dll ,crash in dll. but i not found dmp fille. go version go1.11.5 windows/386.

@gopherbot
Copy link

@gopherbot gopherbot commented Sep 16, 2019

Change https://golang.org/cl/195577 mentions this issue: runtime: enable go programs to crash on windows

@RustamGamidov
Copy link

@RustamGamidov RustamGamidov commented Mar 31, 2020

there's note about WER ui dialog to avoid to run binaries in self-maintained mode.
and there's DontShowUI registry flag to handle that: https://docs.microsoft.com/en-us/windows/win32/wer/wer-settings

@pradipd
Copy link

@pradipd pradipd commented Jun 3, 2020

Is it possible to collect a crash/core dump on windows from an application?
Looking at this thread, and the PR/CL it looks like the only option is to modify go.

I tried setting GOTRACEBACK=crash and I can only get a crashdump using RaiseFailFastException. However, that dump is not very usable in delve. It does not have the stack trace of the crashing thread (I'm pretty sure I need to set the Context, but, I don't know to what). Other go routine's show up all right.
Any insight into this would be appreciated.

@alexbrainman
Copy link
Member

@alexbrainman alexbrainman commented Jun 4, 2020

Is it possible to collect a crash/core dump on windows from an application?
Looking at this thread, and the PR/CL it looks like the only option is to modify go.

Yes, you need to modify Go. You need something like

https://go-review.googlesource.com/c/go/+/195577/

I tried setting GOTRACEBACK=crash and I can only get a crashdump using RaiseFailFastException.

I just discovered RaiseFailFastException. But, yes, RaiseFailFastException might do the trick. The only problem, how do you propose to call RaiseFailFastException when real crash happen? For that you need CL 195577 or similar.

However, that dump is not very usable in delve.

Correct. Delve does not understand Microsoft crash dumps. Microsoft debuggers do. Like WinDbg.

It does not have the stack trace of the crashing thread (I'm pretty sure I need to set the Context, but, I don't know to what). Other go routine's show up all right.

I don't understand this comment.

Alex

@aarzilli
Copy link
Contributor

@aarzilli aarzilli commented Jun 4, 2020

Correct. Delve does not understand Microsoft crash dumps

Actually, it does. Sort of. I've only ever tested with minidumps created by procdump.exe I don't know why the ones created the... "natural" way don't work.

@alexbrainman
Copy link
Member

@alexbrainman alexbrainman commented Jun 6, 2020

Correct. Delve does not understand Microsoft crash dumps

Actually, it does. ...

Thanks for correcting me. I hardly ever use Delve, so I don't keep up with the features. How did you implement the code that reads minidumps? Can you point me to the code?

Thank you.

Alex

@aarzilli
Copy link
Contributor

@aarzilli aarzilli commented Jun 6, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.