summaryrefslogtreecommitdiff
path: root/src/runtime/signal_netbsd_386.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-10-04 07:11:55 -0700
committerIan Lance Taylor <iant@golang.org>2016-10-11 12:56:15 +0000
commitd03e8b226cd11692ca9505a815af559ce7989700 (patch)
tree610aad4dc7c8b726d1f8de864ab994e63baa8339 /src/runtime/signal_netbsd_386.go
parentc24cc40075d77b96bbf1f217dcdcff651229e89b (diff)
downloadgo-git-d03e8b226cd11692ca9505a815af559ce7989700.tar.gz
runtime: record current PC for SIGPROF on non-Go thread
If we get a SIGPROF on a non-Go thread, and the program has not called runtime.SetCgoTraceback so we have no way to collect a stack trace, then record a profile that is just the PC where the signal occurred. That will at least point the user to the right area. Retrieving the PC from the sigctxt in a signal handler on a non-G thread required marking a number of trivial sigctxt methods as nosplit, and, for extra safety, nowritebarrierrec. The test shows that the existing test CgoPprofThread test does not test the stack trace, just the profile signal. Leaving that for later. Change-Id: I8f8f3ff09ac099fc9d9df94b5a9d210ffc20c4ab Reviewed-on: https://go-review.googlesource.com/30252 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime/signal_netbsd_386.go')
-rw-r--r--src/runtime/signal_netbsd_386.go35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/runtime/signal_netbsd_386.go b/src/runtime/signal_netbsd_386.go
index af49d5dec0..845a575268 100644
--- a/src/runtime/signal_netbsd_386.go
+++ b/src/runtime/signal_netbsd_386.go
@@ -11,21 +11,28 @@ type sigctxt struct {
ctxt unsafe.Pointer
}
+//go:nosplit
+//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontextt { return &(*ucontextt)(c.ctxt).uc_mcontext }
-func (c *sigctxt) eax() uint32 { return c.regs().__gregs[_REG_EAX] }
-func (c *sigctxt) ebx() uint32 { return c.regs().__gregs[_REG_EBX] }
-func (c *sigctxt) ecx() uint32 { return c.regs().__gregs[_REG_ECX] }
-func (c *sigctxt) edx() uint32 { return c.regs().__gregs[_REG_EDX] }
-func (c *sigctxt) edi() uint32 { return c.regs().__gregs[_REG_EDI] }
-func (c *sigctxt) esi() uint32 { return c.regs().__gregs[_REG_ESI] }
-func (c *sigctxt) ebp() uint32 { return c.regs().__gregs[_REG_EBP] }
-func (c *sigctxt) esp() uint32 { return c.regs().__gregs[_REG_UESP] }
-func (c *sigctxt) eip() uint32 { return c.regs().__gregs[_REG_EIP] }
-func (c *sigctxt) eflags() uint32 { return c.regs().__gregs[_REG_EFL] }
-func (c *sigctxt) cs() uint32 { return c.regs().__gregs[_REG_CS] }
-func (c *sigctxt) fs() uint32 { return c.regs().__gregs[_REG_FS] }
-func (c *sigctxt) gs() uint32 { return c.regs().__gregs[_REG_GS] }
-func (c *sigctxt) sigcode() uint32 { return uint32(c.info._code) }
+
+func (c *sigctxt) eax() uint32 { return c.regs().__gregs[_REG_EAX] }
+func (c *sigctxt) ebx() uint32 { return c.regs().__gregs[_REG_EBX] }
+func (c *sigctxt) ecx() uint32 { return c.regs().__gregs[_REG_ECX] }
+func (c *sigctxt) edx() uint32 { return c.regs().__gregs[_REG_EDX] }
+func (c *sigctxt) edi() uint32 { return c.regs().__gregs[_REG_EDI] }
+func (c *sigctxt) esi() uint32 { return c.regs().__gregs[_REG_ESI] }
+func (c *sigctxt) ebp() uint32 { return c.regs().__gregs[_REG_EBP] }
+func (c *sigctxt) esp() uint32 { return c.regs().__gregs[_REG_UESP] }
+
+//go:nosplit
+//go:nowritebarrierrec
+func (c *sigctxt) eip() uint32 { return c.regs().__gregs[_REG_EIP] }
+
+func (c *sigctxt) eflags() uint32 { return c.regs().__gregs[_REG_EFL] }
+func (c *sigctxt) cs() uint32 { return c.regs().__gregs[_REG_CS] }
+func (c *sigctxt) fs() uint32 { return c.regs().__gregs[_REG_FS] }
+func (c *sigctxt) gs() uint32 { return c.regs().__gregs[_REG_GS] }
+func (c *sigctxt) sigcode() uint32 { return uint32(c.info._code) }
func (c *sigctxt) sigaddr() uint32 {
return *(*uint32)(unsafe.Pointer(&c.info._reason[0]))
}