gcc/libgo/runtime/go-callers.c
2012-11-01 03:02:13 +00:00

73 lines
1.6 KiB
C

/* 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 "backtrace.h"
#include "runtime.h"
#include "array.h"
/* Argument passed to callback function. */
struct callers_data
{
uintptr *pcbuf;
int index;
int max;
};
/* Callback function for backtrace_simple. Just collect the PC
values. Return zero to continue, non-zero to stop. */
static int
callback (void *data, uintptr_t pc)
{
struct callers_data *arg = (struct callers_data *) data;
arg->pcbuf[arg->index] = pc;
++arg->index;
return arg->index >= arg->max;
}
/* Error callback. */
static void
error_callback (void *data __attribute__ ((unused)),
const char *msg, int errnum)
{
if (errnum != 0)
runtime_printf ("%s errno %d\n", msg, errnum);
runtime_throw (msg);
}
/* Gather caller PC's. */
int32
runtime_callers (int32 skip, uintptr *pcbuf, int32 m)
{
struct callers_data data;
data.pcbuf = pcbuf;
data.index = 0;
data.max = m;
backtrace_simple (__go_get_backtrace_state (), skip + 1, callback,
error_callback, &data);
return data.index;
}
int Callers (int, struct __go_open_array)
__asm__ ("runtime.Callers");
int
Callers (int skip, struct __go_open_array pc)
{
/* In the Go 1 release runtime.Callers has an off-by-one error,
which we can not correct because it would break backward
compatibility. Adjust SKIP here to be compatible. */
return runtime_callers (skip - 1, (uintptr *) pc.__values, pc.__count);
}