github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/src/runtime/os1_windows_386.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import (
     8  	"unsafe"
     9  )
    10  
    11  var text struct{}
    12  
    13  func dumpregs(r *context) {
    14  	print("eax     ", hex(r.eax), "\n")
    15  	print("ebx     ", hex(r.ebx), "\n")
    16  	print("ecx     ", hex(r.ecx), "\n")
    17  	print("edx     ", hex(r.edx), "\n")
    18  	print("edi     ", hex(r.edi), "\n")
    19  	print("esi     ", hex(r.esi), "\n")
    20  	print("ebp     ", hex(r.ebp), "\n")
    21  	print("esp     ", hex(r.esp), "\n")
    22  	print("eip     ", hex(r.eip), "\n")
    23  	print("eflags  ", hex(r.eflags), "\n")
    24  	print("cs      ", hex(r.segcs), "\n")
    25  	print("fs      ", hex(r.segfs), "\n")
    26  	print("gs      ", hex(r.seggs), "\n")
    27  }
    28  
    29  func isgoexception(info *exceptionrecord, r *context) bool {
    30  	// Only handle exception if executing instructions in Go binary
    31  	// (not Windows library code).
    32  	if r.eip < uint32(uintptr(unsafe.Pointer(&text))) || uint32(uintptr(unsafe.Pointer(&etext))) < r.eip {
    33  		return false
    34  	}
    35  
    36  	if issigpanic(info.exceptioncode) == 0 {
    37  		return false
    38  	}
    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  func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
    47  	if !isgoexception(info, r) {
    48  		return _EXCEPTION_CONTINUE_SEARCH
    49  	}
    50  
    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 = uintptr(info.exceptioninformation[0])
    57  	gp.sigcode1 = uintptr(info.exceptioninformation[1])
    58  	gp.sigpc = uintptr(r.eip)
    59  
    60  	// Only push runtime·sigpanic if r->eip != 0.
    61  	// If r->eip == 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.eip != 0 {
    67  		sp := unsafe.Pointer(uintptr(r.esp))
    68  		sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
    69  		*((*uintptr)(sp)) = uintptr(r.eip)
    70  		r.esp = uint32(uintptr(sp))
    71  	}
    72  	r.eip = uint32(funcPC(sigpanic))
    73  	return _EXCEPTION_CONTINUE_EXECUTION
    74  }
    75  
    76  var testingWER bool
    77  
    78  // lastcontinuehandler is reached, because runtime cannot handle
    79  // current exception. lastcontinuehandler will print crash info and exit.
    80  func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
    81  	if testingWER {
    82  		return _EXCEPTION_CONTINUE_SEARCH
    83  	}
    84  
    85  	_g_ := getg()
    86  
    87  	if panicking != 0 { // traceback already printed
    88  		exit(2)
    89  	}
    90  	panicking = 1
    91  
    92  	print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.eip), "\n")
    93  
    94  	print("PC=", hex(r.eip), "\n")
    95  	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
    96  		print("signal arrived during cgo execution\n")
    97  		gp = _g_.m.lockedg
    98  	}
    99  	print("\n")
   100  
   101  	var docrash bool
   102  	if gotraceback(&docrash) > 0 {
   103  		tracebacktrap(uintptr(r.eip), uintptr(r.esp), 0, gp)
   104  		tracebackothers(gp)
   105  		dumpregs(r)
   106  	}
   107  
   108  	if docrash {
   109  		crash()
   110  	}
   111  
   112  	exit(2)
   113  	return 0 // not reached
   114  }
   115  
   116  func sigenable(sig uint32) {
   117  }
   118  
   119  func sigdisable(sig uint32) {
   120  }
   121  
   122  func dosigprof(r *context, gp *g, mp *m) {
   123  	sigprof((*byte)(unsafe.Pointer(uintptr(r.eip))), (*byte)(unsafe.Pointer(uintptr(r.esp))), nil, gp, mp)
   124  }