Skip to content

Commit d053685

Browse files
alexbrainmanwheatman
authored andcommitted
undo CL 145150043 / 8b3d26697b8d
That was complete failure - builders are broken, but original cl worked fine on my system. I will need access to builders to test this change properly. ««« original CL description runtime: handle all windows exception Fixes golang#8006. LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews https://golang.org/cl/145150043 »»» TBR=rsc R=golang-codereviews CC=golang-codereviews https://golang.org/cl/154180043
1 parent 94a1623 commit d053685

9 files changed

+76
-224
lines changed

src/runtime/defs_windows.go

-3
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ const (
5959

6060
INFINITE = C.INFINITE
6161
WAIT_TIMEOUT = C.WAIT_TIMEOUT
62-
63-
EXCEPTION_CONTINUE_EXECUTION = C.EXCEPTION_CONTINUE_EXECUTION
64-
EXCEPTION_CONTINUE_SEARCH = C.EXCEPTION_CONTINUE_SEARCH
6562
)
6663

6764
type SystemInfo C.SYSTEM_INFO

src/runtime/defs_windows_386.h

-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ enum {
3232

3333
INFINITE = 0xffffffff,
3434
WAIT_TIMEOUT = 0x102,
35-
36-
EXCEPTION_CONTINUE_EXECUTION = -0x1,
37-
EXCEPTION_CONTINUE_SEARCH = 0x0,
3835
};
3936

4037
typedef struct SystemInfo SystemInfo;

src/runtime/defs_windows_amd64.h

-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ enum {
3232

3333
INFINITE = 0xffffffff,
3434
WAIT_TIMEOUT = 0x102,
35-
36-
EXCEPTION_CONTINUE_EXECUTION = -0x1,
37-
EXCEPTION_CONTINUE_SEARCH = 0x0,
3835
};
3936

4037
typedef struct SystemInfo SystemInfo;

src/runtime/os_windows.c

+6-29
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
3535
#pragma dynimport runtime·SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
3636
#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
37-
#pragma dynimport runtime·SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
3837
#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
3938
#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
4039
#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
@@ -66,7 +65,6 @@ extern void *runtime·SetConsoleCtrlHandler;
6665
extern void *runtime·SetEvent;
6766
extern void *runtime·SetProcessPriorityBoost;
6867
extern void *runtime·SetThreadPriority;
69-
extern void *runtime·SetUnhandledExceptionFilter;
7068
extern void *runtime·SetWaitableTimer;
7169
extern void *runtime·Sleep;
7270
extern void *runtime·SuspendThread;
@@ -79,9 +77,7 @@ void *runtime·GetQueuedCompletionStatusEx;
7977

8078
extern uintptr runtime·externalthreadhandlerp;
8179
void runtime·externalthreadhandler(void);
82-
void runtime·exceptiontramp(void);
83-
void runtime·firstcontinuetramp(void);
84-
void runtime·lastcontinuetramp(void);
80+
void runtime·sigtramp(void);
8581

8682
#pragma textflag NOSPLIT
8783
uintptr
@@ -110,28 +106,12 @@ void
110106
runtime·osinit(void)
111107
{
112108
void *kernel32;
113-
void *addVectoredContinueHandler = nil;
114-
115-
kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
116109

117110
runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
118111

119-
runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·exceptiontramp);
120-
if(kernel32 != nil)
121-
addVectoredContinueHandler = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"AddVectoredContinueHandler");
122-
if(addVectoredContinueHandler == nil)
123-
// use SetUnhandledExceptionFilter if VectoredContinueHandler is unavailable.
124-
// note: SetUnhandledExceptionFilter handler won't be called, if debugging.
125-
runtime·stdcall1(runtime·SetUnhandledExceptionFilter, (uintptr)runtime·lastcontinuetramp);
126-
else {
127-
runtime·stdcall2(addVectoredContinueHandler, 1, (uintptr)runtime·firstcontinuetramp);
128-
runtime·stdcall2(addVectoredContinueHandler, 0, (uintptr)runtime·lastcontinuetramp);
129-
}
130-
112+
runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·sigtramp);
131113
runtime·stdcall2(runtime·SetConsoleCtrlHandler, (uintptr)runtime·ctrlhandler, 1);
132-
133114
runtime·stdcall1(runtime·timeBeginPeriod, 1);
134-
135115
runtime·ncpu = getproccount();
136116

137117
// Windows dynamic priority boosting assumes that a process has different types
@@ -140,6 +120,7 @@ runtime·osinit(void)
140120
// In such context dynamic priority boosting does nothing but harm, so we turn it off.
141121
runtime·stdcall2(runtime·SetProcessPriorityBoost, -1, 1);
142122

123+
kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
143124
if(kernel32 != nil) {
144125
runtime·GetQueuedCompletionStatusEx = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"GetQueuedCompletionStatusEx");
145126
}
@@ -494,14 +475,10 @@ runtime·issigpanic(uint32 code)
494475
void
495476
runtime·initsig(void)
496477
{
497-
// following line keeps these functions alive at link stage
478+
// following line keeps sigtramp alive at link stage
498479
// if there's a better way please write it here
499-
void *e = runtime·exceptiontramp;
500-
void *f = runtime·firstcontinuetramp;
501-
void *l = runtime·lastcontinuetramp;
502-
USED(e);
503-
USED(f);
504-
USED(l);
480+
void *p = runtime·sigtramp;
481+
USED(p);
505482
}
506483

507484
uint32

src/runtime/os_windows_386.c

+33-51
Original file line numberDiff line numberDiff line change
@@ -24,63 +24,45 @@ runtime·dumpregs(Context *r)
2424
runtime·printf("gs %x\n", r->SegGs);
2525
}
2626

27-
bool
28-
runtime·isgoexception(ExceptionRecord *info, Context *r)
27+
// Called by sigtramp from Windows VEH handler.
28+
// Return value signals whether the exception has been handled (-1)
29+
// or should be made available to other handlers in the chain (0).
30+
uint32
31+
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
2932
{
33+
bool crash;
34+
uintptr *sp;
3035
extern byte runtime·text[], runtime·etext[];
3136

3237
// Only handle exception if executing instructions in Go binary
3338
// (not Windows library code).
3439
if(r->Eip < (uint32)runtime·text || (uint32)runtime·etext < r->Eip)
35-
return false;
36-
37-
if(!runtime·issigpanic(info->ExceptionCode))
38-
return false;
39-
40-
return true;
41-
}
42-
43-
// Called by sigtramp from Windows VEH handler.
44-
// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
45-
// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
46-
uint32
47-
runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
48-
{
49-
uintptr *sp;
50-
51-
if(!runtime·isgoexception(info, r))
52-
return EXCEPTION_CONTINUE_SEARCH;
53-
54-
// Make it look like a call to the signal func.
55-
// Have to pass arguments out of band since
56-
// augmenting the stack frame would break
57-
// the unwinding code.
58-
gp->sig = info->ExceptionCode;
59-
gp->sigcode0 = info->ExceptionInformation[0];
60-
gp->sigcode1 = info->ExceptionInformation[1];
61-
gp->sigpc = r->Eip;
62-
63-
// Only push runtime·sigpanic if r->eip != 0.
64-
// If r->eip == 0, probably panicked because of a
65-
// call to a nil func. Not pushing that onto sp will
66-
// make the trace look like a call to runtime·sigpanic instead.
67-
// (Otherwise the trace will end at runtime·sigpanic and we
68-
// won't get to see who faulted.)
69-
if(r->Eip != 0) {
70-
sp = (uintptr*)r->Esp;
71-
*--sp = r->Eip;
72-
r->Esp = (uintptr)sp;
40+
return 0;
41+
42+
if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
43+
// Make it look like a call to the signal func.
44+
// Have to pass arguments out of band since
45+
// augmenting the stack frame would break
46+
// the unwinding code.
47+
gp->sig = info->ExceptionCode;
48+
gp->sigcode0 = info->ExceptionInformation[0];
49+
gp->sigcode1 = info->ExceptionInformation[1];
50+
gp->sigpc = r->Eip;
51+
52+
// Only push runtime·sigpanic if r->eip != 0.
53+
// If r->eip == 0, probably panicked because of a
54+
// call to a nil func. Not pushing that onto sp will
55+
// make the trace look like a call to runtime·sigpanic instead.
56+
// (Otherwise the trace will end at runtime·sigpanic and we
57+
// won't get to see who faulted.)
58+
if(r->Eip != 0) {
59+
sp = (uintptr*)r->Esp;
60+
*--sp = r->Eip;
61+
r->Esp = (uintptr)sp;
62+
}
63+
r->Eip = (uintptr)runtime·sigpanic;
64+
return -1;
7365
}
74-
r->Eip = (uintptr)runtime·sigpanic;
75-
return EXCEPTION_CONTINUE_EXECUTION;
76-
}
77-
78-
// lastcontinuehandler is reached, because runtime cannot handle
79-
// current exception. lastcontinuehandler will print crash info and exit.
80-
uint32
81-
runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
82-
{
83-
bool crash;
8466

8567
if(runtime·panicking) // traceback already printed
8668
runtime·exit(2);
@@ -106,7 +88,7 @@ runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
10688
runtime·crash();
10789

10890
runtime·exit(2);
109-
return 0; // not reached
91+
return -1; // not reached
11092
}
11193

11294
void

src/runtime/os_windows_amd64.c

+33-64
Original file line numberDiff line numberDiff line change
@@ -32,76 +32,45 @@ runtime·dumpregs(Context *r)
3232
runtime·printf("gs %X\n", (uint64)r->SegGs);
3333
}
3434

35-
bool
36-
runtime·isgoexception(ExceptionRecord *info, Context *r)
35+
// Called by sigtramp from Windows VEH handler.
36+
// Return value signals whether the exception has been handled (-1)
37+
// or should be made available to other handlers in the chain (0).
38+
uint32
39+
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
3740
{
41+
bool crash;
42+
uintptr *sp;
3843
extern byte runtime·text[], runtime·etext[];
3944

4045
// Only handle exception if executing instructions in Go binary
4146
// (not Windows library code).
4247
if(r->Rip < (uint64)runtime·text || (uint64)runtime·etext < r->Rip)
43-
return false;
44-
45-
if(!runtime·issigpanic(info->ExceptionCode))
46-
return false;
47-
48-
return true;
49-
}
50-
51-
// Called by sigtramp from Windows VEH handler.
52-
// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
53-
// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
54-
uint32
55-
runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
56-
{
57-
uintptr *sp;
58-
59-
if(!runtime·isgoexception(info, r))
60-
return EXCEPTION_CONTINUE_SEARCH;
61-
62-
// Make it look like a call to the signal func.
63-
// Have to pass arguments out of band since
64-
// augmenting the stack frame would break
65-
// the unwinding code.
66-
gp->sig = info->ExceptionCode;
67-
gp->sigcode0 = info->ExceptionInformation[0];
68-
gp->sigcode1 = info->ExceptionInformation[1];
69-
gp->sigpc = r->Rip;
70-
71-
// Only push runtime·sigpanic if r->rip != 0.
72-
// If r->rip == 0, probably panicked because of a
73-
// call to a nil func. Not pushing that onto sp will
74-
// make the trace look like a call to runtime·sigpanic instead.
75-
// (Otherwise the trace will end at runtime·sigpanic and we
76-
// won't get to see who faulted.)
77-
if(r->Rip != 0) {
78-
sp = (uintptr*)r->Rsp;
79-
*--sp = r->Rip;
80-
r->Rsp = (uintptr)sp;
48+
return 0;
49+
50+
if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
51+
// Make it look like a call to the signal func.
52+
// Have to pass arguments out of band since
53+
// augmenting the stack frame would break
54+
// the unwinding code.
55+
gp->sig = info->ExceptionCode;
56+
gp->sigcode0 = info->ExceptionInformation[0];
57+
gp->sigcode1 = info->ExceptionInformation[1];
58+
gp->sigpc = r->Rip;
59+
60+
// Only push runtime·sigpanic if r->rip != 0.
61+
// If r->rip == 0, probably panicked because of a
62+
// call to a nil func. Not pushing that onto sp will
63+
// make the trace look like a call to runtime·sigpanic instead.
64+
// (Otherwise the trace will end at runtime·sigpanic and we
65+
// won't get to see who faulted.)
66+
if(r->Rip != 0) {
67+
sp = (uintptr*)r->Rsp;
68+
*--sp = r->Rip;
69+
r->Rsp = (uintptr)sp;
70+
}
71+
r->Rip = (uintptr)runtime·sigpanic;
72+
return -1;
8173
}
82-
r->Rip = (uintptr)runtime·sigpanic;
83-
return EXCEPTION_CONTINUE_EXECUTION;
84-
}
85-
86-
// It seems Windows searches ContinueHandler's list even
87-
// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
88-
// firstcontinuehandler will stop that search,
89-
// if exceptionhandler did the same earlier.
90-
uint32
91-
runtime·firstcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
92-
{
93-
USED(gp);
94-
if(!runtime·isgoexception(info, r))
95-
return EXCEPTION_CONTINUE_SEARCH;
96-
return EXCEPTION_CONTINUE_EXECUTION;
97-
}
98-
99-
// lastcontinuehandler is reached, because runtime cannot handle
100-
// current exception. lastcontinuehandler will print crash info and exit.
101-
uint32
102-
runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
103-
{
104-
bool crash;
10574

10675
if(runtime·panicking) // traceback already printed
10776
runtime·exit(2);
@@ -128,7 +97,7 @@ runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
12897
runtime·crash();
12998

13099
runtime·exit(2);
131-
return 0; // not reached
100+
return -1; // not reached
132101
}
133102

134103
void

src/runtime/sys_windows_386.s

+2-16
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ TEXT runtime·setlasterror(SB),NOSPLIT,$0
7373
// Called by Windows as a Vectored Exception Handler (VEH).
7474
// First argument is pointer to struct containing
7575
// exception record and context pointers.
76-
// Handler function is stored in AX.
7776
// Return 0 for 'not handled', -1 for handled.
7877
TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
7978
MOVL ptrs+0(FP), CX
@@ -85,8 +84,6 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
8584
MOVL SI, 20(SP)
8685
MOVL DI, 24(SP)
8786

88-
MOVL AX, SI // save handler address
89-
9087
// find g
9188
get_tls(DX)
9289
CMPL DX, $0
@@ -126,10 +123,11 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
126123
sigtramp_g0:
127124
MOVL 0(CX), BX // ExceptionRecord*
128125
MOVL 4(CX), CX // Context*
126+
// call sighandler(ExceptionRecord*, Context*, G*)
129127
MOVL BX, 0(SP)
130128
MOVL CX, 4(SP)
131129
MOVL DX, 8(SP)
132-
CALL SI // call handler
130+
CALL runtime·sighandler(SB)
133131
// AX is set to report result back to Windows
134132
MOVL 12(SP), AX
135133

@@ -151,18 +149,6 @@ done:
151149
// RET 4 (return and pop 4 bytes parameters)
152150
BYTE $0xC2; WORD $4
153151
RET // unreached; make assembler happy
154-
155-
TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
156-
MOVL $runtime·exceptionhandler(SB), AX
157-
JMP runtime·sigtramp(SB)
158-
159-
TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
160-
// is never called
161-
INT $3
162-
163-
TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
164-
MOVL $runtime·lastcontinuehandler(SB), AX
165-
JMP runtime·sigtramp(SB)
166152

167153
TEXT runtime·ctrlhandler(SB),NOSPLIT,$0
168154
PUSHL $runtime·ctrlhandler1(SB)

0 commit comments

Comments
 (0)