Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
d7b8f2b7
Commit
d7b8f2b7
authored
May 17, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
runtime: Print stack trace on panic or signal.
From-SVN: r187623
parent
8730965e
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
262 additions
and
61 deletions
+262
-61
libgo/Makefile.am
+1
-0
libgo/Makefile.in
+36
-26
libgo/runtime/go-signal.c
+41
-13
libgo/runtime/go-traceback.c
+62
-0
libgo/runtime/mprof.goc
+5
-4
libgo/runtime/proc.c
+70
-9
libgo/runtime/runtime.c
+33
-6
libgo/runtime/runtime.h
+14
-3
No files found.
libgo/Makefile.am
View file @
d7b8f2b7
...
@@ -439,6 +439,7 @@ runtime_files = \
...
@@ -439,6 +439,7 @@ runtime_files = \
runtime/go-string-to-int-array.c
\
runtime/go-string-to-int-array.c
\
runtime/go-strplus.c
\
runtime/go-strplus.c
\
runtime/go-strslice.c
\
runtime/go-strslice.c
\
runtime/go-traceback.c
\
runtime/go-trampoline.c
\
runtime/go-trampoline.c
\
runtime/go-type-complex.c
\
runtime/go-type-complex.c
\
runtime/go-type-eface.c
\
runtime/go-type-eface.c
\
...
...
libgo/Makefile.in
View file @
d7b8f2b7
...
@@ -197,22 +197,23 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \
...
@@ -197,22 +197,23 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \
runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c
\
runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c
\
runtime/go-string-to-byte-array.c
\
runtime/go-string-to-byte-array.c
\
runtime/go-string-to-int-array.c runtime/go-strplus.c
\
runtime/go-string-to-int-array.c runtime/go-strplus.c
\
runtime/go-strslice.c runtime/go-trampoline.c
\
runtime/go-strslice.c runtime/go-traceback.c
\
runtime/go-type-complex.c runtime/go-type-eface.c
\
runtime/go-trampoline.c runtime/go-type-complex.c
\
runtime/go-type-error.c runtime/go-type-float.c
\
runtime/go-type-eface.c runtime/go-type-error.c
\
runtime/go-type-identity.c runtime/go-type-interface.c
\
runtime/go-type-float.c runtime/go-type-identity.c
\
runtime/go-type-string.c runtime/go-typedesc-equal.c
\
runtime/go-type-interface.c runtime/go-type-string.c
\
runtime/go-typestring.c runtime/go-unsafe-new.c
\
runtime/go-typedesc-equal.c runtime/go-typestring.c
\
runtime/go-unsafe-newarray.c runtime/go-unsafe-pointer.c
\
runtime/go-unsafe-new.c runtime/go-unsafe-newarray.c
\
runtime/go-unwind.c runtime/chan.c runtime/cpuprof.c
\
runtime/go-unsafe-pointer.c runtime/go-unwind.c runtime/chan.c
\
runtime/lock_sema.c runtime/thread-sema.c runtime/lock_futex.c
\
runtime/cpuprof.c runtime/lock_sema.c runtime/thread-sema.c
\
runtime/thread-linux.c runtime/mcache.c runtime/mcentral.c
\
runtime/lock_futex.c runtime/thread-linux.c runtime/mcache.c
\
runtime/mem_posix_memalign.c runtime/mem.c runtime/mfinal.c
\
runtime/mcentral.c runtime/mem_posix_memalign.c runtime/mem.c
\
runtime/mfixalloc.c runtime/mgc0.c runtime/mheap.c
\
runtime/mfinal.c runtime/mfixalloc.c runtime/mgc0.c
\
runtime/msize.c runtime/proc.c runtime/runtime.c
\
runtime/mheap.c runtime/msize.c runtime/proc.c
\
runtime/signal_unix.c runtime/thread.c runtime/yield.c
\
runtime/runtime.c runtime/signal_unix.c runtime/thread.c
\
runtime/rtems-task-variable-add.c iface.c malloc.c map.c
\
runtime/yield.c runtime/rtems-task-variable-add.c iface.c
\
mprof.c reflect.c runtime1.c sema.c sigqueue.c string.c time.c
malloc.c map.c mprof.c reflect.c runtime1.c sema.c sigqueue.c
\
string.c time.c
@LIBGO_IS_LINUX_FALSE@
am__objects_1
=
lock_sema.lo thread-sema.lo
@LIBGO_IS_LINUX_FALSE@
am__objects_1
=
lock_sema.lo thread-sema.lo
@LIBGO_IS_LINUX_TRUE@
am__objects_1
=
lock_futex.lo thread-linux.lo
@LIBGO_IS_LINUX_TRUE@
am__objects_1
=
lock_futex.lo thread-linux.lo
@HAVE_SYS_MMAN_H_FALSE@
am__objects_2
=
mem_posix_memalign.lo
@HAVE_SYS_MMAN_H_FALSE@
am__objects_2
=
mem_posix_memalign.lo
...
@@ -234,16 +235,16 @@ am__objects_4 = go-append.lo go-assert.lo go-assert-interface.lo \
...
@@ -234,16 +235,16 @@ am__objects_4 = go-append.lo go-assert.lo go-assert-interface.lo \
go-reflect-map.lo go-rune.lo go-runtime-error.lo go-setenv.lo
\
go-reflect-map.lo go-rune.lo go-runtime-error.lo go-setenv.lo
\
go-signal.lo go-strcmp.lo go-string-to-byte-array.lo
\
go-signal.lo go-strcmp.lo go-string-to-byte-array.lo
\
go-string-to-int-array.lo go-strplus.lo go-strslice.lo
\
go-string-to-int-array.lo go-strplus.lo go-strslice.lo
\
go-tra
mpoline.lo go-type-complex.lo go-type-eface
.lo
\
go-tra
ceback.lo go-trampoline.lo go-type-complex
.lo
\
go-type-e
rror.lo go-type-float.lo go-type-identity
.lo
\
go-type-e
face.lo go-type-error.lo go-type-float
.lo
\
go-type-i
nterface.lo go-type-string.lo go-typedesc-equal
.lo
\
go-type-i
dentity.lo go-type-interface.lo go-type-string
.lo
\
go-type
string.lo go-unsafe-new.lo go-unsafe-newarray
.lo
\
go-type
desc-equal.lo go-typestring.lo go-unsafe-new
.lo
\
go-unsafe-
pointer.lo go-unwind.lo chan.lo cpuprof
.lo
\
go-unsafe-
newarray.lo go-unsafe-pointer.lo go-unwind
.lo
\
$(am__objects_1)
mcache.lo mcentral.lo
$(am__objects_2)
\
chan.lo cpuprof.lo
$(am__objects_1)
mcache.lo mcentral.lo
\
mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo proc
.lo
\
$(am__objects_2)
mfinal.lo mfixalloc.lo mgc0.lo mheap
.lo
\
runtime.lo signal_unix.lo thread.lo yield.lo
$(am__objects_3)
\
msize.lo proc.lo runtime.lo signal_unix.lo thread.lo yield.lo
\
iface.lo malloc.lo map.lo mprof.lo reflect.lo runtime1
.lo
\
$(am__objects_3)
iface.lo malloc.lo map.lo mprof.lo reflect
.lo
\
sema.lo sigqueue.lo string.lo time.lo
runtime1.lo
sema.lo sigqueue.lo string.lo time.lo
am_libgo_la_OBJECTS
=
$(am__objects_4)
am_libgo_la_OBJECTS
=
$(am__objects_4)
libgo_la_OBJECTS
=
$(am_libgo_la_OBJECTS)
libgo_la_OBJECTS
=
$(am_libgo_la_OBJECTS)
libgo_la_LINK
=
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
\
libgo_la_LINK
=
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
\
...
@@ -855,6 +856,7 @@ runtime_files = \
...
@@ -855,6 +856,7 @@ runtime_files = \
runtime/go-string-to-int-array.c
\
runtime/go-string-to-int-array.c
\
runtime/go-strplus.c
\
runtime/go-strplus.c
\
runtime/go-strslice.c
\
runtime/go-strslice.c
\
runtime/go-traceback.c
\
runtime/go-trampoline.c
\
runtime/go-trampoline.c
\
runtime/go-type-complex.c
\
runtime/go-type-complex.c
\
runtime/go-type-eface.c
\
runtime/go-type-eface.c
\
...
@@ -2408,6 +2410,7 @@ distclean-compile:
...
@@ -2408,6 +2410,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-string-to-int-array.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-string-to-int-array.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-strplus.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-strplus.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-strslice.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-strslice.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-traceback.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-trampoline.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-trampoline.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-type-complex.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-type-complex.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-type-eface.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/go-type-eface.Plo@am__quote@
...
@@ -2823,6 +2826,13 @@ go-strslice.lo: runtime/go-strslice.c
...
@@ -2823,6 +2826,13 @@ go-strslice.lo: runtime/go-strslice.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@
DEPDIR
=
$(DEPDIR)
$(CCDEPMODE)
$(depcomp)
@AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@
DEPDIR
=
$(DEPDIR)
$(CCDEPMODE)
$(depcomp)
@AMDEPBACKSLASH@
@am__fastdepCC_FALSE@
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
--mode
=
compile
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
-c
-o
go-strslice.lo
`
test
-f
'runtime/go-strslice.c'
||
echo
'
$(srcdir)
/'
`
runtime/go-strslice.c
@am__fastdepCC_FALSE@
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
--mode
=
compile
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
-c
-o
go-strslice.lo
`
test
-f
'runtime/go-strslice.c'
||
echo
'
$(srcdir)
/'
`
runtime/go-strslice.c
go-traceback.lo
:
runtime/go-traceback.c
@am__fastdepCC_TRUE@
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
--mode
=
compile
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
-MT
go-traceback.lo
-MD
-MP
-MF
$(DEPDIR)
/go-traceback.Tpo
-c
-o
go-traceback.lo
`
test
-f
'runtime/go-traceback.c'
||
echo
'
$(srcdir)
/'
`
runtime/go-traceback.c
@am__fastdepCC_TRUE@
$(am__mv)
$(DEPDIR)/go-traceback.Tpo
$(DEPDIR)/go-traceback.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@
source
=
'runtime/go-traceback.c'
object
=
'go-traceback.lo'
libtool
=
yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@
DEPDIR
=
$(DEPDIR)
$(CCDEPMODE)
$(depcomp)
@AMDEPBACKSLASH@
@am__fastdepCC_FALSE@
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
--mode
=
compile
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
-c
-o
go-traceback.lo
`
test
-f
'runtime/go-traceback.c'
||
echo
'
$(srcdir)
/'
`
runtime/go-traceback.c
go-trampoline.lo
:
runtime/go-trampoline.c
go-trampoline.lo
:
runtime/go-trampoline.c
@am__fastdepCC_TRUE@
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
--mode
=
compile
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
-MT
go-trampoline.lo
-MD
-MP
-MF
$(DEPDIR)
/go-trampoline.Tpo
-c
-o
go-trampoline.lo
`
test
-f
'runtime/go-trampoline.c'
||
echo
'
$(srcdir)
/'
`
runtime/go-trampoline.c
@am__fastdepCC_TRUE@
$(LIBTOOL)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
$(LIBTOOLFLAGS)
--mode
=
compile
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
-MT
go-trampoline.lo
-MD
-MP
-MF
$(DEPDIR)
/go-trampoline.Tpo
-c
-o
go-trampoline.lo
`
test
-f
'runtime/go-trampoline.c'
||
echo
'
$(srcdir)
/'
`
runtime/go-trampoline.c
@am__fastdepCC_TRUE@
$(am__mv)
$(DEPDIR)/go-trampoline.Tpo
$(DEPDIR)/go-trampoline.Plo
@am__fastdepCC_TRUE@
$(am__mv)
$(DEPDIR)/go-trampoline.Tpo
$(DEPDIR)/go-trampoline.Plo
...
...
libgo/runtime/go-signal.c
View file @
d7b8f2b7
...
@@ -157,7 +157,6 @@ sig_handler (int sig)
...
@@ -157,7 +157,6 @@ sig_handler (int sig)
for
(
i
=
0
;
runtime_sigtab
[
i
].
sig
!=
-
1
;
++
i
)
for
(
i
=
0
;
runtime_sigtab
[
i
].
sig
!=
-
1
;
++
i
)
{
{
struct
sigaction
sa
;
SigTab
*
t
;
SigTab
*
t
;
t
=
&
runtime_sigtab
[
i
];
t
=
&
runtime_sigtab
[
i
];
...
@@ -177,21 +176,33 @@ sig_handler (int sig)
...
@@ -177,21 +176,33 @@ sig_handler (int sig)
runtime_startpanic
();
runtime_startpanic
();
/* We should do a stack backtrace here. Until we can do that,
{
we reraise the signal in order to get a slightly better
const
char
*
name
=
NULL
;
report from the shell. */
memset
(
&
sa
,
0
,
sizeof
sa
);
#ifdef HAVE_STRSIGNAL
name
=
strsignal
(
sig
);
#endif
sa
.
sa_handler
=
SIG_DFL
;
if
(
name
==
NULL
)
runtime_printf
(
"Signal %d
\n
"
,
sig
);
else
runtime_printf
(
"%s
\n
"
,
name
);
}
i
=
sigemptyset
(
&
sa
.
sa_mask
);
runtime_printf
(
"
\n
"
);
__go_assert
(
i
==
0
);
if
(
sigaction
(
sig
,
&
sa
,
NULL
)
!=
0
)
if
(
runtime_gotraceback
())
abort
();
{
G
*
g
;
raise
(
sig
);
g
=
runtime_g
();
runtime_traceback
(
g
);
runtime_tracebackothers
(
g
);
/* The gc library calls runtime_dumpregs here, and provides
a function that prints the registers saved in context in
a readable form. */
}
runtime_exit
(
2
);
runtime_exit
(
2
);
}
}
...
@@ -230,12 +241,22 @@ static void
...
@@ -230,12 +241,22 @@ static void
sig_panic_info_handler
(
int
sig
,
siginfo_t
*
info
,
sig_panic_info_handler
(
int
sig
,
siginfo_t
*
info
,
void
*
context
__attribute__
((
unused
)))
void
*
context
__attribute__
((
unused
)))
{
{
if
(
runtime_g
()
==
NULL
||
info
->
si_code
==
SI_USER
)
G
*
g
;
g
=
runtime_g
();
if
(
g
==
NULL
||
info
->
si_code
==
SI_USER
)
{
{
sig_handler
(
sig
);
sig_handler
(
sig
);
return
;
return
;
}
}
g
->
sig
=
sig
;
g
->
sigcode0
=
info
->
si_code
;
g
->
sigcode1
=
(
uintptr_t
)
info
->
si_addr
;
/* It would be nice to set g->sigpc here as the gc library does, but
I don't know how to get it portably. */
sig_panic_leadin
(
sig
);
sig_panic_leadin
(
sig
);
switch
(
sig
)
switch
(
sig
)
...
@@ -284,12 +305,19 @@ sig_panic_info_handler (int sig, siginfo_t *info,
...
@@ -284,12 +305,19 @@ sig_panic_info_handler (int sig, siginfo_t *info,
static
void
static
void
sig_panic_handler
(
int
sig
)
sig_panic_handler
(
int
sig
)
{
{
if
(
runtime_g
()
==
NULL
)
G
*
g
;
g
=
runtime_g
();
if
(
g
==
NULL
)
{
{
sig_handler
(
sig
);
sig_handler
(
sig
);
return
;
return
;
}
}
g
->
sig
=
sig
;
g
->
sigcode0
=
0
;
g
->
sigcode1
=
0
;
sig_panic_leadin
(
sig
);
sig_panic_leadin
(
sig
);
switch
(
sig
)
switch
(
sig
)
...
...
libgo/runtime/go-traceback.c
0 → 100644
View file @
d7b8f2b7
/* go-traceback.c -- stack backtrace for Go.
Copyright 2012 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */
#include "config.h"
#include "unwind.h"
#include "runtime.h"
#include "go-string.h"
static
_Unwind_Reason_Code
traceback
(
struct
_Unwind_Context
*
context
,
void
*
varg
)
{
int
*
parg
=
(
int
*
)
varg
;
uintptr
pc
;
int
ip_before_insn
=
0
;
struct
__go_string
fn
;
struct
__go_string
file
;
int
line
;
#ifdef HAVE_GETIPINFO
pc
=
_Unwind_GetIPInfo
(
context
,
&
ip_before_insn
);
#else
pc
=
_Unwind_GetIP
(
context
);
#endif
if
(
*
parg
>
100
)
return
_URC_END_OF_STACK
;
++*
parg
;
/* FIXME: If PC is in the __morestack routine, we should ignore
it. */
/* Back up to the call instruction. */
if
(
!
ip_before_insn
)
--
pc
;
if
(
!
__go_file_line
(
pc
,
&
fn
,
&
file
,
&
line
))
return
_URC_END_OF_STACK
;
if
(
runtime_showframe
(
fn
.
__data
))
{
runtime_printf
(
"%s
\n
"
,
fn
.
__data
);
runtime_printf
(
"
\t
%s:%d
\n
"
,
file
.
__data
,
line
);
}
return
_URC_NO_REASON
;
}
/* Print a stack trace for the current goroutine. */
void
runtime_traceback
()
{
int
c
;
c
=
0
;
_Unwind_Backtrace
(
traceback
,
&
c
);
}
libgo/runtime/mprof.goc
View file @
d7b8f2b7
...
@@ -361,10 +361,11 @@ func Stack(b Slice, all bool) (n int32) {
...
@@ -361,10 +361,11 @@ func Stack(b Slice, all bool) (n int32) {
g
->
writenbuf
=
b
.
__count
;
g
->
writenbuf
=
b
.
__count
;
USED
(
pc
);
USED
(
pc
);
USED
(
sp
);
USED
(
sp
);
//
runtime_goroutineheader
(
g
);
runtime_goroutineheader
(
g
);
//
runtime_traceback
(
pc
,
sp
,
0
,
g
);
runtime_traceback
();
//
if
(
all
)
runtime_goroutinetrailer
(
g
);
//
runtime_tracebackothers
(
g
);
if
(
all
)
runtime_tracebackothers
(
g
);
n
=
b
.
__count
-
g
->
writenbuf
;
n
=
b
.
__count
-
g
->
writenbuf
;
g
->
writebuf
=
nil
;
g
->
writebuf
=
nil
;
g
->
writenbuf
=
0
;
g
->
writenbuf
=
0
;
...
...
libgo/runtime/proc.c
View file @
d7b8f2b7
...
@@ -50,6 +50,8 @@ uintptr runtime_stacks_sys;
...
@@ -50,6 +50,8 @@ uintptr runtime_stacks_sys;
static
void
schedule
(
G
*
);
static
void
schedule
(
G
*
);
static
void
gtraceback
(
G
*
);
typedef
struct
Sched
Sched
;
typedef
struct
Sched
Sched
;
M
runtime_m0
;
M
runtime_m0
;
...
@@ -345,6 +347,9 @@ runtime_mcall(void (*pfn)(G*))
...
@@ -345,6 +347,9 @@ runtime_mcall(void (*pfn)(G*))
// the values for this thread.
// the values for this thread.
mp
=
runtime_m
();
mp
=
runtime_m
();
gp
=
runtime_g
();
gp
=
runtime_g
();
if
(
gp
->
dotraceback
!=
nil
)
gtraceback
(
gp
);
}
}
if
(
gp
==
nil
||
!
gp
->
fromgogo
)
{
if
(
gp
==
nil
||
!
gp
->
fromgogo
)
{
#ifdef USING_SPLIT_STACK
#ifdef USING_SPLIT_STACK
...
@@ -523,19 +528,73 @@ runtime_goroutineheader(G *g)
...
@@ -523,19 +528,73 @@ runtime_goroutineheader(G *g)
}
}
void
void
runtime_
tracebackothers
(
G
*
me
)
runtime_
goroutinetrailer
(
G
*
g
)
{
{
G
*
g
;
if
(
g
!=
nil
&&
g
->
gopc
!=
0
&&
g
->
goid
!=
1
)
{
struct
__go_string
fn
;
struct
__go_string
file
;
int
line
;
if
(
__go_file_line
(
g
->
gopc
-
1
,
&
fn
,
&
file
,
&
line
))
{
runtime_printf
(
"created by %s
\n
"
,
fn
.
__data
);
runtime_printf
(
"
\t
%s:%d
\n
"
,
file
.
__data
,
line
);
}
}
}
void
runtime_tracebackothers
(
G
*
volatile
me
)
{
G
*
volatile
g
;
for
(
g
=
runtime_allg
;
g
!=
nil
;
g
=
g
->
alllink
)
{
for
(
g
=
runtime_allg
;
g
!=
nil
;
g
=
g
->
alllink
)
{
if
(
g
==
me
||
g
->
status
==
Gdead
)
if
(
g
==
me
||
g
->
status
==
Gdead
)
continue
;
continue
;
runtime_printf
(
"
\n
"
);
runtime_printf
(
"
\n
"
);
runtime_goroutineheader
(
g
);
runtime_goroutineheader
(
g
);
// runtime_traceback(g->sched.pc, g->sched.sp, 0, g);
// Our only mechanism for doing a stack trace is
// _Unwind_Backtrace. And that only works for the
// current thread, not for other random goroutines.
// So we need to switch context to the goroutine, get
// the backtrace, and then switch back.
// This means that if g is running or in a syscall, we
// can't reliably print a stack trace. FIXME.
if
(
g
->
status
==
Gsyscall
||
g
->
status
==
Grunning
)
{
runtime_printf
(
"no stack trace available
\n
"
);
runtime_goroutinetrailer
(
g
);
continue
;
}
g
->
dotraceback
=
me
;
#ifdef USING_SPLIT_STACK
__splitstack_getcontext
(
&
me
->
stack_context
[
0
]);
#endif
getcontext
(
&
me
->
context
);
if
(
g
->
dotraceback
)
{
runtime_gogo
(
g
);
}
}
}
}
}
// Do a stack trace of gp, and then restore the context to
// gp->dotraceback.
static
void
gtraceback
(
G
*
gp
)
{
G
*
ret
;
runtime_traceback
(
nil
);
runtime_goroutinetrailer
(
gp
);
ret
=
gp
->
dotraceback
;
gp
->
dotraceback
=
nil
;
runtime_gogo
(
ret
);
}
// Mark this g as m's idle goroutine.
// Mark this g as m's idle goroutine.
// This functionality might be used in environments where programs
// This functionality might be used in environments where programs
// are limited to a single thread, to simulate a select-driven
// are limited to a single thread, to simulate a select-driven
...
@@ -1171,7 +1230,7 @@ runtime_entersyscall(void)
...
@@ -1171,7 +1230,7 @@ runtime_entersyscall(void)
// Leave SP around for gc and traceback.
// Leave SP around for gc and traceback.
#ifdef USING_SPLIT_STACK
#ifdef USING_SPLIT_STACK
g
->
gcstack
=
__splitstack_find
(
NULL
,
NULL
,
&
g
->
gcstack_size
,
g
->
gcstack
=
__splitstack_find
(
nil
,
nil
,
&
g
->
gcstack_size
,
&
g
->
gcnext_segment
,
&
g
->
gcnext_sp
,
&
g
->
gcnext_segment
,
&
g
->
gcnext_sp
,
&
g
->
gcinitial_sp
);
&
g
->
gcinitial_sp
);
#else
#else
...
@@ -1227,9 +1286,11 @@ runtime_exitsyscall(void)
...
@@ -1227,9 +1286,11 @@ runtime_exitsyscall(void)
// find that we still have mcpu <= mcpumax, then we can
// find that we still have mcpu <= mcpumax, then we can
// start executing Go code immediately, without having to
// start executing Go code immediately, without having to
// schedlock/schedunlock.
// schedlock/schedunlock.
// Also do fast return if any locks are held, so that
// panic code can use syscalls to open a file.
gp
=
g
;
gp
=
g
;
v
=
runtime_xadd
(
&
runtime_sched
.
atomic
,
(
1
<<
mcpuShift
));
v
=
runtime_xadd
(
&
runtime_sched
.
atomic
,
(
1
<<
mcpuShift
));
if
(
m
->
profilehz
==
runtime_sched
.
profilehz
&&
atomic_mcpu
(
v
)
<=
atomic_mcpumax
(
v
)
)
{
if
(
(
m
->
profilehz
==
runtime_sched
.
profilehz
&&
atomic_mcpu
(
v
)
<=
atomic_mcpumax
(
v
))
||
m
->
locks
>
0
)
{
// There's a cpu for us, so we can run.
// There's a cpu for us, so we can run.
gp
->
status
=
Grunning
;
gp
->
status
=
Grunning
;
// Garbage collector isn't running (since we are),
// Garbage collector isn't running (since we are),
...
@@ -1561,7 +1622,7 @@ runtime_sigprof(uint8 *pc __attribute__ ((unused)),
...
@@ -1561,7 +1622,7 @@ runtime_sigprof(uint8 *pc __attribute__ ((unused)),
uint8
*
lr
__attribute__
((
unused
)),
uint8
*
lr
__attribute__
((
unused
)),
G
*
gp
__attribute__
((
unused
)))
G
*
gp
__attribute__
((
unused
)))
{
{
//
int32 n;
int32
n
;
if
(
prof
.
fn
==
nil
||
prof
.
hz
==
0
)
if
(
prof
.
fn
==
nil
||
prof
.
hz
==
0
)
return
;
return
;
...
@@ -1571,9 +1632,9 @@ runtime_sigprof(uint8 *pc __attribute__ ((unused)),
...
@@ -1571,9 +1632,9 @@ runtime_sigprof(uint8 *pc __attribute__ ((unused)),
runtime_unlock
(
&
prof
);
runtime_unlock
(
&
prof
);
return
;
return
;
}
}
// n = runtime_gentraceback(pc, sp, lr, gp,
0, prof.pcbuf, nelem(prof.pcbuf));
n
=
runtime_callers
(
0
,
prof
.
pcbuf
,
nelem
(
prof
.
pcbuf
));
//
if(n > 0)
if
(
n
>
0
)
//
prof.fn(prof.pcbuf, n);
prof
.
fn
(
prof
.
pcbuf
,
n
);
runtime_unlock
(
&
prof
);
runtime_unlock
(
&
prof
);
}
}
...
...
libgo/runtime/runtime.c
View file @
d7b8f2b7
...
@@ -11,6 +11,17 @@
...
@@ -11,6 +11,17 @@
uint32
runtime_panicking
;
uint32
runtime_panicking
;
int32
runtime_gotraceback
(
void
)
{
const
byte
*
p
;
p
=
runtime_getenv
(
"GOTRACEBACK"
);
if
(
p
==
nil
||
p
[
0
]
==
'\0'
)
return
1
;
// default is on
return
runtime_atoi
(
p
);
}
static
Lock
paniclk
;
static
Lock
paniclk
;
void
void
...
@@ -31,20 +42,26 @@ runtime_startpanic(void)
...
@@ -31,20 +42,26 @@ runtime_startpanic(void)
void
void
runtime_dopanic
(
int32
unused
__attribute__
((
unused
)))
runtime_dopanic
(
int32
unused
__attribute__
((
unused
)))
{
{
/*
G
*
g
;
static
bool
didothers
;
static
bool
didothers
;
g
=
runtime_g
();
if
(
g
->
sig
!=
0
)
if
(
g
->
sig
!=
0
)
runtime_printf("[signal %x code=%p addr=%p
pc=%p
]\n",
runtime_printf
(
"[signal %x code=%p addr=%p]
\n
"
,
g->sig,
g->sigcode0, g->sigcode1, g->sigpc
);
g
->
sig
,
(
void
*
)(
g
->
sigcode0
),
(
void
*
)(
g
->
sigcode1
)
);
if
(
runtime_gotraceback
()){
if
(
runtime_gotraceback
()){
if
(
g
!=
runtime_m
()
->
g0
)
{
runtime_printf
(
"
\n
"
);
runtime_goroutineheader
(
g
);
runtime_traceback
();
runtime_goroutinetrailer
(
g
);
}
if
(
!
didothers
)
{
if
(
!
didothers
)
{
didothers
=
true
;
didothers
=
true
;
runtime_tracebackothers
(
g
);
runtime_tracebackothers
(
g
);
}
}
}
}
*/
runtime_unlock
(
&
paniclk
);
runtime_unlock
(
&
paniclk
);
if
(
runtime_xadd
(
&
runtime_panicking
,
-
1
)
!=
0
)
{
if
(
runtime_xadd
(
&
runtime_panicking
,
-
1
)
!=
0
)
{
...
@@ -185,10 +202,10 @@ runtime_fastrand1(void)
...
@@ -185,10 +202,10 @@ runtime_fastrand1(void)
}
}
static
struct
root_list
runtime_roots
=
static
struct
root_list
runtime_roots
=
{
NULL
,
{
nil
,
{
{
&
syscall_Envs
,
sizeof
syscall_Envs
},
{
{
&
syscall_Envs
,
sizeof
syscall_Envs
},
{
&
os_Args
,
sizeof
os_Args
},
{
&
os_Args
,
sizeof
os_Args
},
{
NULL
,
0
}
},
{
nil
,
0
}
},
};
};
void
void
...
@@ -209,3 +226,13 @@ runtime_cputicks(void)
...
@@ -209,3 +226,13 @@ runtime_cputicks(void)
return
0
;
return
0
;
#endif
#endif
}
}
bool
runtime_showframe
(
const
unsigned
char
*
s
)
{
static
int32
traceback
=
-
1
;
if
(
traceback
<
0
)
traceback
=
runtime_gotraceback
();
return
traceback
>
1
||
(
__builtin_strchr
((
const
char
*
)
s
,
'.'
)
!=
nil
&&
__builtin_memcmp
(
s
,
"runtime."
,
7
)
!=
0
);
}
libgo/runtime/runtime.h
View file @
d7b8f2b7
...
@@ -143,14 +143,16 @@ struct G
...
@@ -143,14 +143,16 @@ struct G
M
*
m
;
// for debuggers, but offset not hard-coded
M
*
m
;
// for debuggers, but offset not hard-coded
M
*
lockedm
;
M
*
lockedm
;
M
*
idlem
;
M
*
idlem
;
//
int32 sig;
int32
sig
;
int32
writenbuf
;
int32
writenbuf
;
byte
*
writebuf
;
byte
*
writebuf
;
//
uintptr sigcode0;
uintptr
sigcode0
;
//
uintptr sigcode1;
uintptr
sigcode1
;
// uintptr sigpc;
// uintptr sigpc;
uintptr
gopc
;
// pc of go statement that created this goroutine
uintptr
gopc
;
// pc of go statement that created this goroutine
G
*
dotraceback
;
ucontext_t
context
;
ucontext_t
context
;
void
*
stack_context
[
10
];
void
*
stack_context
[
10
];
};
};
...
@@ -289,6 +291,11 @@ void* runtime_mal(uintptr);
...
@@ -289,6 +291,11 @@ void* runtime_mal(uintptr);
void
runtime_schedinit
(
void
);
void
runtime_schedinit
(
void
);
void
runtime_initsig
(
void
);
void
runtime_initsig
(
void
);
void
runtime_sigenable
(
uint32
sig
);
void
runtime_sigenable
(
uint32
sig
);
int32
runtime_gotraceback
(
void
);
void
runtime_goroutineheader
(
G
*
);
void
runtime_goroutinetrailer
(
G
*
);
void
runtime_traceback
();
void
runtime_tracebackothers
(
G
*
);
String
runtime_gostringnocopy
(
const
byte
*
);
String
runtime_gostringnocopy
(
const
byte
*
);
void
*
runtime_mstart
(
void
*
);
void
*
runtime_mstart
(
void
*
);
G
*
runtime_malg
(
int32
,
byte
**
,
size_t
*
);
G
*
runtime_malg
(
int32
,
byte
**
,
size_t
*
);
...
@@ -434,6 +441,8 @@ void runtime_osyield(void);
...
@@ -434,6 +441,8 @@ void runtime_osyield(void);
void
runtime_LockOSThread
(
void
)
__asm__
(
"runtime.LockOSThread"
);
void
runtime_LockOSThread
(
void
)
__asm__
(
"runtime.LockOSThread"
);
void
runtime_UnlockOSThread
(
void
)
__asm__
(
"runtime.UnlockOSThread"
);
void
runtime_UnlockOSThread
(
void
)
__asm__
(
"runtime.UnlockOSThread"
);
bool
runtime_showframe
(
const
unsigned
char
*
);
uintptr
runtime_memlimit
(
void
);
uintptr
runtime_memlimit
(
void
);
// If appropriate, ask the operating system to control whether this
// If appropriate, ask the operating system to control whether this
...
@@ -468,3 +477,5 @@ void __go_register_gc_roots(struct root_list*);
...
@@ -468,3 +477,5 @@ void __go_register_gc_roots(struct root_list*);
// This will be 0 when using split stacks, as in that case
// This will be 0 when using split stacks, as in that case
// the stacks are allocated by the splitstack library.
// the stacks are allocated by the splitstack library.
extern
uintptr
runtime_stacks_sys
;
extern
uintptr
runtime_stacks_sys
;
extern
_Bool
__go_file_line
(
uintptr
,
String
*
,
String
*
,
int
*
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment