blob: 09556c33c7ac8c1f266deb6d7f8755d4978512ac (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
/* go-callers.c -- get callers 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"
/* Argument passed to backtrace function. */
struct callers_data
{
int skip;
uintptr *pcbuf;
int index;
int max;
};
static _Unwind_Reason_Code
backtrace (struct _Unwind_Context *context, void *varg)
{
struct callers_data *arg = (struct callers_data *) varg;
uintptr pc;
int ip_before_insn = 0;
#ifdef HAVE_GETIPINFO
pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
pc = _Unwind_GetIP (context);
#endif
/* FIXME: If PC is in the __morestack routine, we should ignore
it. */
if (arg->skip > 0)
--arg->skip;
else if (arg->index >= arg->max)
return _URC_END_OF_STACK;
else
{
/* Here PC will be the return address. We actually want the
address of the call instruction, so back up one byte and
count on the lookup routines handling that correctly. */
if (!ip_before_insn)
--pc;
arg->pcbuf[arg->index] = pc;
++arg->index;
}
return _URC_NO_REASON;
}
int32
runtime_callers (int32 skip, uintptr *pcbuf, int32 m)
{
struct callers_data arg;
arg.skip = skip + 1;
arg.pcbuf = pcbuf;
arg.index = 0;
arg.max = m;
_Unwind_Backtrace (backtrace, &arg);
return arg.index;
}
int Callers (int, struct __go_open_array)
__asm__ ("libgo_runtime.runtime.Callers");
int
Callers (int skip, struct __go_open_array pc)
{
return runtime_callers (skip, (uintptr *) pc.__values, pc.__count);
}
|