summaryrefslogtreecommitdiff
path: root/libgo/runtime/go-traceback.c
blob: 2ff2ce3faef3434c5e3e0a4b9dfc2df9de13d0a8 (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
/* 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);
}