problem with two uwps in the same frame on windows
Bug #379472 reported by
Nikodemus Siivola
This bug affects 2 people
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
High
|
Unassigned |
Bug Description
(defun bad ()
(unwind-protect
(catch :oops
t))
t))
(bad)
; results in...
;
; An exception occurred in context #.(SB-SYS:INT-SAP #X0022E964): #.(SB-SYS:INT-SAP #X0022E950). (Exception code: 3221225513)
; [Condition of type SIMPLE-ERROR]
;
;
; whereas the exact same control flow in two different functions is
; fine
(defun good ()
(unwind-protect
(ext)
t))
(defun ext ()
(catch :oops
(unwind-protect
(throw :oops :out)
t)))
(good) ; => :OUT
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
To post a comment you must log in.
A fragment of a trace-file for BAD shows:
> IR1 block 4 start c38 BINDING- POINTER => t2[S36]<t32[EAX] STACK-POINTER => t1[S37] BINDING- POINTER => t6[S32]<t37[EAX] STACK-POINTER => t5[S33] 41[Const6] >t42[EDX] BINDING- POINTER => t10[S28]<t44[EAX] STACK-POINTER => t9[S29] Const7] >t50[EDX] => t51[EDX] 41[Const6] >t54[EDX] t52[EBX] t53[ECX]
>
> IR2 block 10 start c38
> 0: CURRENT-
> 1: SAVE-DYNAMIC-STATE => t3[S35]<t33[EAX] t4[S34]<t34[ECX]
> 2: CURRENT-
> 3: MAKE-UNWIND-BLOCK t35[S19] {#<SB-ASSEM:LABEL 4>} => t36[ECX]
> 4: SET-UNWIND-PROTECT t35[S19]
>
> IR1 block 5 start c56
>
> IR2 block 9 start c56
> 0: CURRENT-
> 1: SAVE-DYNAMIC-STATE => t7[S31]<t38[EAX] t8[S30]<t39[ECX]
> 2: CURRENT-
> 3: MAKE-CATCH-BLOCK t40[S12] ':OOPS!
> {#<SB-ASSEM:LABEL 5>}
> => t43[ECX]
>
> IR1 block 6 start c79
>
> IR2 block 8 start c79
>
> IR1 block 7 start c87
>
> IR2 block 7 start c87
> 0: CURRENT-
> 1: SAVE-DYNAMIC-STATE => t11[S27]<t45[EAX] t12[S26]<t46[ECX]
> 2: CURRENT-
> 3: MAKE-UNWIND-BLOCK t47[S5] {#<SB-ASSEM:LABEL 6>} => t48[ECX]
> 4: SET-UNWIND-PROTECT t47[S5]
> 5: MOVE ':OUT!49[
> 6: PUSH-VALUES t51[EDX] {1} => t52[EBX] t53[ECX]
> 7: THROW ':OOPS!
Note the two uses of SET-UNWIND-PROTECT. The first one is for t35[S19], the second for t47[S5]. The values S19 and S5 indicate a negative (expand-down) stack offset within the frame. S19 is [EBP-104] and S5 is [EBP-48]. Win32 is picky about its exception frames, and what this does is disorder the frame chain (the topmost SEH frame is deeper in the stack than the next-topmost SEH frame). We are also lucky that this constraint is only checked for unwind destinations, as if it were checked during full unwind the process would have been killed when choosing any restart from the debugger.
Essentially, I recommend changing the stack frame layout policy and hoping that it fixes the problem.