summaryrefslogtreecommitdiff
path: root/runtime/caml/debugger.h
blob: f5b27f618f572c083fd5267b874d762ecfd2d106 (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**************************************************************************/
/*                                                                        */
/*                                 OCaml                                  */
/*                                                                        */
/*             Xavier Leroy, projet Cristal, INRIA Rocquencourt           */
/*                                                                        */
/*   Copyright 1996 Institut National de Recherche en Informatique et     */
/*     en Automatique.                                                    */
/*                                                                        */
/*   All rights reserved.  This file is distributed under the terms of    */
/*   the GNU Lesser General Public License version 2.1, with the          */
/*   special exception on linking described in the file LICENSE.          */
/*                                                                        */
/**************************************************************************/

/* Interface with the debugger */

#ifndef CAML_DEBUGGER_H
#define CAML_DEBUGGER_H

#ifdef CAML_INTERNALS

#include "misc.h"
#include "mlvalues.h"

CAMLextern int caml_debugger_in_use;
CAMLextern int caml_debugger_fork_mode; /* non-zero for parent */
extern uintnat caml_event_count;

enum event_kind {
  EVENT_COUNT, BREAKPOINT, PROGRAM_START, PROGRAM_EXIT,
  TRAP_BARRIER, UNCAUGHT_EXC, DEBUG_INFO_ADDED,
  CODE_LOADED, CODE_UNLOADED
};

void caml_debugger_init (void);
void caml_debugger (enum event_kind event, value param);
void caml_debugger_cleanup_fork (void);

opcode_t caml_debugger_saved_instruction(code_t pc);

/* Communication protocol */

/* Requests from the debugger to the runtime system */

enum debugger_request {
  REQ_SET_EVENT = 'e',          /* uint32_t pos */
  /* Set an event on the instruction at position pos */
  REQ_SET_BREAKPOINT = 'B',     /* uint32_t pos, (char k) */
  /* Set a breakpoint at position pos */
  /* In profiling mode, the breakpoint kind is set to k */
  REQ_RESET_INSTR = 'i',        /* uint32_t pos */
  /* Clear an event or breapoint at position pos, restores initial instr. */
  REQ_CHECKPOINT = 'c',         /* no args */
  /* Checkpoint the runtime system by forking a child process.
     Reply is pid of child process or -1 if checkpoint failed. */
  REQ_GO = 'g',                 /* uint32_t n */
  /* Run the program for n events.
     Reply is one of debugger_reply described below. */
  REQ_STOP = 's',               /* no args */
  /* Terminate the runtime system */
  REQ_WAIT = 'w',               /* no args */
  /* Reap one dead child (a discarded checkpoint). */
  REQ_INITIAL_FRAME = '0',      /* no args */
  /* Set current frame to bottom frame (the one currently executing).
     Reply is stack offset and current pc. */
  REQ_GET_FRAME = 'f',          /* no args */
  /* Return current frame location (stack offset + current pc). */
  REQ_SET_FRAME = 'S',          /* uint32_t stack_offset */
  /* Set current frame to given stack offset. No reply. */
  REQ_UP_FRAME = 'U',           /* uint32_t n */
  /* Move one frame up. Argument n is size of current frame (in words).
     Reply is stack offset and current pc, or -1 if top of stack reached. */
  REQ_SET_TRAP_BARRIER = 'b',   /* uint32_t offset */
  /* Set the trap barrier at the given offset. */
  REQ_GET_LOCAL = 'L',          /* uint32_t slot_number */
  /* Return the local variable at the given slot in the current frame.
     Reply is one value. */
  REQ_GET_ENVIRONMENT = 'E',    /* uint32_t slot_number */
  /* Return the local variable at the given slot in the heap environment
     of the current frame. Reply is one value. */
  REQ_GET_GLOBAL = 'G',         /* uint32_t global_number */
  /* Return the specified global variable. Reply is one value. */
  REQ_GET_ACCU = 'A',           /* no args */
  /* Return the current contents of the accumulator. Reply is one value. */
  REQ_GET_HEADER = 'H',         /* mlvalue v */
  /* As REQ_GET_OBJ, but sends only the header. */
  REQ_GET_FIELD = 'F',          /* mlvalue v, uint32_t fieldnum */
  /* As REQ_GET_OBJ, but sends only one field. */
  REQ_MARSHAL_OBJ = 'M',        /* mlvalue v */
  /* Send a copy of the data structure rooted at v, using the same
     format as [caml_output_value]. */
  REQ_GET_CLOSURE_CODE = 'C',   /* mlvalue v */
  /* Send the code address of the given closure.
     Reply is one uint32_t. */
  REQ_SET_FORK_MODE = 'K'       /* uint32_t m */
  /* Set whether to follow the child (m=0) or the parent on fork. */
};

/* Replies to a REQ_GO request. All replies are followed by three uint32_t:
   - the value of the event counter
   - the position of the stack
   - the current pc.
   The REP_CODE_DEBUG_INFO reply is also followed by:
   - the newly added debug information.
   The REP_CODE_{UN,}LOADED reply is also followed by:
   - the code fragment index. */

enum debugger_reply {
  REP_EVENT = 'e',
  /* Event counter reached 0. */
  REP_BREAKPOINT = 'b',
  /* Breakpoint hit. */
  REP_EXITED = 'x',
  /* Program exited by calling exit or reaching the end of the source. */
  REP_TRAP = 's',
  /* Trap barrier crossed. */
  REP_UNCAUGHT_EXC = 'u',
  /* Program exited due to a stray exception. */
  REP_CODE_DEBUG_INFO = 'D',
  /* Additional debug info loaded. */
  REP_CODE_LOADED = 'L',
  /* Additional code loaded. */
  REP_CODE_UNLOADED = 'U',
  /* Additional code unloaded. */
};

#endif /* CAML_INTERNALS */

#endif /* CAML_DEBUGGER_H */