github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/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  // lastcontinuehandler is reached, because runtime cannot handle
    77  // current exception. lastcontinuehandler will print crash info and exit.
    78  func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
    79  	_g_ := getg()
    80  
    81  	if panicking != 0 { // traceback already printed
    82  		exit(2)
    83  	}
    84  	panicking = 1
    85  
    86  	print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.eip), "\n")
    87  
    88  	print("PC=", hex(r.eip), "\n")
    89  	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
    90  		print("signal arrived during cgo execution\n")
    91  		gp = _g_.m.lockedg
    92  	}
    93  	print("\n")
    94  
    95  	var docrash bool
    96  	if gotraceback(&docrash) > 0 {
    97  		tracebacktrap(uintptr(r.eip), uintptr(r.esp), 0, gp)
    98  		tracebackothers(gp)
    99  		dumpregs(r)
   100  	}
   101  
   102  	if docrash {
   103  		crash()
   104  	}
   105  
   106  	exit(2)
   107  	return 0 // not reached
   108  }
   109  
   110  func sigenable(sig uint32) {
   111  }
   112  
   113  func sigdisable(sig uint32) {
   114  }
   115  
   116  func dosigprof(r *context, gp *g, mp *m) {
   117  	sigprof((*byte)(unsafe.Pointer(uintptr(r.eip))), (*byte)(unsafe.Pointer(uintptr(r.esp))), nil, gp, mp)
   118  }