/
haiku_debugger.h
690 lines (572 loc) · 22.8 KB
/
haiku_debugger.h
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
/*
* Copyright 2005-2016 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _DEBUGGER_H
#define _DEBUGGER_H
#include "BeDefs.h"
#include "haiku_image.h"
#include "haiku_signal.h"
// include architecture specific definitions
#include <arch_debugger.h>
#if defined(__x86_64__)
typedef struct x86_64_debug_cpu_state debug_cpu_state;
#elif defined(__i386__)
typedef struct x86_debug_cpu_state debug_cpu_state;
#elif defined(__POWERPC__)
typedef struct ppc_debug_cpu_state debug_cpu_state;
#elif defined(__M68K__)
typedef struct m68k_debug_cpu_state debug_cpu_state;
#elif defined(__MIPSEL__)
typedef struct mipsel_debug_cpu_state debug_cpu_state;
#elif defined(__arm__)
typedef struct arm_debug_cpu_state debug_cpu_state;
#elif (defined(__riscv) && __riscv_xlen == 64)
typedef struct riscv64_debug_cpu_state debug_cpu_state;
#elif defined(__sparc64__)
typedef struct sparc_debug_cpu_state debug_cpu_state;
#elif defined(__aarch64__) || defined(__arm64__)
typedef struct arm64_debug_cpu_state debug_cpu_state;
#else
#error unsupported architecture
#endif
#ifdef __cplusplus
extern "C"
{
#endif
// team debugging flags
enum
{
// event mask: If a flag is set, any of the team's threads will stop when
// the respective event occurs. None of the flags are enabled by default.
// Always enabled are debugger() calls and hardware exceptions, as well as
// the deletion of the debugged team.
B_TEAM_DEBUG_SIGNALS = 0x00010000,
B_TEAM_DEBUG_PRE_SYSCALL = 0x00020000,
B_TEAM_DEBUG_POST_SYSCALL = 0x00040000,
B_TEAM_DEBUG_TEAM_CREATION = 0x00080000,
B_TEAM_DEBUG_THREADS = 0x00100000,
B_TEAM_DEBUG_IMAGES = 0x00200000,
B_TEAM_DEBUG_PREVENT_EXIT = 0x00400000,
// new thread handling
B_TEAM_DEBUG_STOP_NEW_THREADS = 0x01000000,
B_TEAM_DEBUG_USER_FLAG_MASK = 0xffff0000,
};
// per-thread debugging flags
enum
{
// event mask: If a flag is set, the thread will stop when the respective
// event occurs. If there is a corresponding team flag, it is sufficient,
// if either is set. Per default none of the flags is set.
B_THREAD_DEBUG_PRE_SYSCALL = 0x00010000,
B_THREAD_DEBUG_POST_SYSCALL = 0x00020000,
// child thread handling
B_THREAD_DEBUG_STOP_CHILD_THREADS = 0x00100000,
B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS = 0x00200000,
B_THREAD_DEBUG_USER_FLAG_MASK = 0xffff0000,
};
// in case of a B_EXCEPTION_OCCURRED event: the type of the exception
typedef enum
{
B_NON_MASKABLE_INTERRUPT = 0,
B_MACHINE_CHECK_EXCEPTION,
B_SEGMENT_VIOLATION,
B_ALIGNMENT_EXCEPTION,
B_DIVIDE_ERROR,
B_OVERFLOW_EXCEPTION,
B_BOUNDS_CHECK_EXCEPTION,
B_INVALID_OPCODE_EXCEPTION,
B_SEGMENT_NOT_PRESENT,
B_STACK_FAULT,
B_GENERAL_PROTECTION_FAULT,
B_FLOATING_POINT_EXCEPTION,
} debug_exception_type;
// Value indicating how a stopped thread shall continue.
enum
{
B_THREAD_DEBUG_HANDLE_EVENT = 0, // handle the event normally
// (e.g. a signal is delivered, a
// CPU fault kills the team,...)
B_THREAD_DEBUG_IGNORE_EVENT, // ignore the event and continue as if
// it didn't occur (e.g. a signal or
// a CPU fault will be ignored)
};
// watchpoint types (ToDo: Check PPC support.)
enum
{
B_DATA_READ_WATCHPOINT = 0, // !x86
B_DATA_WRITE_WATCHPOINT,
B_DATA_READ_WRITE_WATCHPOINT,
};
// how to apply signal ignore masks
typedef enum
{
B_DEBUG_SIGNAL_MASK_AND = 0,
B_DEBUG_SIGNAL_MASK_OR,
B_DEBUG_SIGNAL_MASK_SET,
} debug_signal_mask_op;
#define B_DEBUG_SIGNAL_TO_MASK(signal) (1ULL << ((signal)-1))
// maximal number of bytes to read/write via B_DEBUG_MESSAGE_{READ,WRITE]_MEMORY
enum
{
B_MAX_READ_WRITE_MEMORY_SIZE = 1024,
};
// messages to the debug nub thread
typedef enum
{
B_DEBUG_MESSAGE_READ_MEMORY = 0, // read from the team's memory
B_DEBUG_MESSAGE_WRITE_MEMORY, // write to the team's memory
B_DEBUG_MESSAGE_SET_TEAM_FLAGS, // set the team's debugging flags
B_DEBUG_MESSAGE_SET_THREAD_FLAGS, // set a thread's debugging flags
B_DEBUG_MESSAGE_CONTINUE_THREAD, // continue a stopped thread
B_DEBUG_MESSAGE_SET_CPU_STATE, // change a stopped thread's CPU state
B_DEBUG_MESSAGE_GET_CPU_STATE, // get the thread's current CPU state
B_DEBUG_MESSAGE_SET_BREAKPOINT, // set a breakpoint
B_DEBUG_MESSAGE_CLEAR_BREAKPOINT, // clear a breakpoint
B_DEBUG_MESSAGE_SET_WATCHPOINT, // set a watchpoint
B_DEBUG_MESSAGE_CLEAR_WATCHPOINT, // clear a watchpoint
B_DEBUG_MESSAGE_SET_SIGNAL_MASKS, // set/get a thread's masks of signals
B_DEBUG_MESSAGE_GET_SIGNAL_MASKS, // the debugger is interested in
B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER, // set/get the team's signal handler for
B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER, // a signal
B_DEBUG_MESSAGE_PREPARE_HANDOVER, // prepares the debugged team for being
// handed over to another debugger;
// the new debugger can just invoke
// install_team_debugger()
B_DEBUG_START_PROFILER, // start/stop sampling
B_DEBUG_STOP_PROFILER, //
B_DEBUG_WRITE_CORE_FILE // write a core file
} debug_nub_message;
// messages sent to the debugger
typedef enum
{
B_DEBUGGER_MESSAGE_THREAD_DEBUGGED = 0, // debugger message in reaction to
// an invocation of debug_thread()
B_DEBUGGER_MESSAGE_DEBUGGER_CALL, // thread called debugger()
B_DEBUGGER_MESSAGE_BREAKPOINT_HIT, // thread hit a breakpoint
B_DEBUGGER_MESSAGE_WATCHPOINT_HIT, // thread hit a watchpoint
B_DEBUGGER_MESSAGE_SINGLE_STEP, // thread was single-stepped
B_DEBUGGER_MESSAGE_PRE_SYSCALL, // begin of a syscall
B_DEBUGGER_MESSAGE_POST_SYSCALL, // end of a syscall
B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED, // thread received a signal
B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED, // an exception occurred
B_DEBUGGER_MESSAGE_TEAM_CREATED, // the debugged team created a new
// one
B_DEBUGGER_MESSAGE_TEAM_DELETED, // the debugged team is gone
B_DEBUGGER_MESSAGE_TEAM_EXEC, // the debugged team executes exec()
B_DEBUGGER_MESSAGE_THREAD_CREATED, // a thread has been created
B_DEBUGGER_MESSAGE_THREAD_DELETED, // a thread has been deleted
B_DEBUGGER_MESSAGE_IMAGE_CREATED, // an image has been created
B_DEBUGGER_MESSAGE_IMAGE_DELETED, // an image has been deleted
B_DEBUGGER_MESSAGE_PROFILER_UPDATE, // flush the profiling buffer for a
// thread
B_DEBUGGER_MESSAGE_HANDED_OVER, // the debugged team has been
// handed over to another debugger,
// sent to both debuggers
} debug_debugger_message;
// profile events -- when the buffer is in variable stack depth format, a sample
// count entry >= B_DEBUG_PROFILE_EVENT_BASE indicates a profile event
enum
{
B_DEBUG_PROFILE_EVENT_BASE = 0x80000000,
B_DEBUG_PROFILE_EVENT_PARAMETER_MASK = 0x0000ffff,
// & with to get the event's parameter count
B_DEBUG_PROFILE_IMAGE_EVENT = 0x80010001
// single parameter: the respective image event counter
};
// #pragma mark -
// #pragma mark ----- messages to the debug nub thread -----
// B_DEBUG_MESSAGE_READ_MEMORY
typedef struct
{
port_id reply_port; // port to send the reply to
void *address; // address from which to read
int32 size; // number of bytes to read
} debug_nub_read_memory;
typedef struct
{
status_t error; // B_OK, if reading went fine
int32 size; // the number of bytes actually read
// > 0, iff error == B_OK
char data[B_MAX_READ_WRITE_MEMORY_SIZE];
// the read data
} debug_nub_read_memory_reply;
// B_DEBUG_MESSAGE_WRITE_MEMORY
typedef struct
{
port_id reply_port; // port to send the reply to
void *address; // address to which to write
int32 size; // number of bytes to write
char data[B_MAX_READ_WRITE_MEMORY_SIZE];
// data to write
} debug_nub_write_memory;
typedef struct
{
status_t error; // B_OK, if writing went fine
int32 size; // the number of bytes actually written
} debug_nub_write_memory_reply;
// B_DEBUG_MESSAGE_SET_TEAM_FLAGS
typedef struct
{
int32 flags; // the new team debugging flags
} debug_nub_set_team_flags;
// B_DEBUG_MESSAGE_SET_THREAD_FLAGS
typedef struct
{
thread_id thread; // the thread
int32 flags; // the new thread debugging flags
} debug_nub_set_thread_flags;
// B_DEBUG_MESSAGE_CONTINUE_THREAD
typedef struct
{
thread_id thread; // the thread
uint32 handle_event; // how to handle the occurred event
bool single_step; // true == single step, false == run full speed
} debug_nub_continue_thread;
// B_DEBUG_MESSAGE_SET_CPU_STATE
typedef struct
{
thread_id thread; // the thread
debug_cpu_state cpu_state; // the new CPU state
} debug_nub_set_cpu_state;
// B_DEBUG_MESSAGE_GET_CPU_STATE
typedef struct
{
port_id reply_port; // port to send the reply to
thread_id thread; // the thread
} debug_nub_get_cpu_state;
typedef struct
{
status_t error; // != B_OK, if something went wrong
// (bad thread ID, thread not stopped)
debug_debugger_message message; // the reason why the thread stopped
debug_cpu_state cpu_state; // the thread's CPU state
} debug_nub_get_cpu_state_reply;
// B_DEBUG_MESSAGE_SET_BREAKPOINT
typedef struct
{
port_id reply_port; // port to send the reply to
void *address; // breakpoint address
} debug_nub_set_breakpoint;
typedef struct
{
status_t error; // B_OK, if the breakpoint has been set
// successfully
} debug_nub_set_breakpoint_reply;
// B_DEBUG_MESSAGE_CLEAR_BREAKPOINT
typedef struct
{
void *address; // breakpoint address
} debug_nub_clear_breakpoint;
// B_DEBUG_MESSAGE_SET_WATCHPOINT
typedef struct
{
port_id reply_port; // port to send the reply to
void *address; // watchpoint address
uint32 type; // watchpoint type (see type constants above)
int32 length; // number of bytes to watch (typically 1, 2,
// 4); architecture specific alignment
// restrictions apply.
} debug_nub_set_watchpoint;
typedef struct
{
status_t error; // B_OK, if the watchpoint has been set
// successfully
} debug_nub_set_watchpoint_reply;
// B_DEBUG_MESSAGE_CLEAR_WATCHPOINT
typedef struct
{
void *address; // watchpoint address
} debug_nub_clear_watchpoint;
// B_DEBUG_MESSAGE_SET_SIGNAL_MASKS
typedef struct
{
thread_id thread; // the thread
uint64 ignore_mask; // the mask for signals the
// debugger wishes not to be
// notified of
uint64 ignore_once_mask; // the mask for signals the
// debugger wishes not to be
// notified of when they next
// occur
debug_signal_mask_op ignore_op; // what to do with ignore_mask
debug_signal_mask_op ignore_once_op; // what to do with
// ignore_once_mask
} debug_nub_set_signal_masks;
// B_DEBUG_MESSAGE_GET_SIGNAL_MASKS
typedef struct
{
port_id reply_port; // port to send the reply to
thread_id thread; // the thread
} debug_nub_get_signal_masks;
typedef struct
{
status_t error; // B_OK, if the thread exists
uint64 ignore_mask; // the mask for signals the debugger wishes
// not to be notified of
uint64 ignore_once_mask; // the mask for signals the debugger wishes
// not to be notified of when they next
// occur
} debug_nub_get_signal_masks_reply;
// B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER
typedef struct
{
int signal; // the signal
struct haiku_sigaction handler; // the new signal handler
} debug_nub_set_signal_handler;
// B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER
typedef struct
{
port_id reply_port; // port to send the reply to
int signal; // the signal
} debug_nub_get_signal_handler;
typedef struct
{
status_t error; // B_OK, if the thread exists
struct haiku_sigaction handler; // the signal handler
} debug_nub_get_signal_handler_reply;
// B_DEBUG_MESSAGE_PREPARE_HANDOVER
// no parameters, no reply
// B_DEBUG_START_PROFILER
struct debug_profile_function
{
addr_t base; // function base address
size_t size; // function size
};
typedef struct
{
port_id reply_port; // port to send the reply to
thread_id thread; // thread to profile
bigtime_t interval; // sample interval
area_id sample_area; // area into which the sample will be
// written
int32 stack_depth; // number of return address per hit
bool variable_stack_depth;
// variable number of samples per hit;
// cf. debug_profiler_update
} debug_nub_start_profiler;
typedef struct
{
status_t error;
int32 image_event; // number of the last image event
bigtime_t interval; // actual sample interval (might
// differ from the requested one)
} debug_nub_start_profiler_reply;
// B_DEBUG_STOP_PROFILER
typedef struct
{
port_id reply_port; // port to send the reply to
thread_id thread; // thread to profile
} debug_nub_stop_profiler;
// B_DEBUG_WRITE_CORE_FILE
typedef struct
{
port_id reply_port; // port to send the reply to
char path[B_PATH_NAME_LENGTH];
// path of the core file; must not exist
// yet; must be absolute
} debug_nub_write_core_file;
typedef struct
{
status_t error; // B_OK on success
} debug_nub_write_core_file_reply;
// reply is debug_profiler_update
// union of all messages structures sent to the debug nub thread
typedef union
{
debug_nub_read_memory read_memory;
debug_nub_write_memory write_memory;
debug_nub_set_team_flags set_team_flags;
debug_nub_set_thread_flags set_thread_flags;
debug_nub_continue_thread continue_thread;
debug_nub_set_cpu_state set_cpu_state;
debug_nub_get_cpu_state get_cpu_state;
debug_nub_set_breakpoint set_breakpoint;
debug_nub_clear_breakpoint clear_breakpoint;
debug_nub_set_watchpoint set_watchpoint;
debug_nub_clear_watchpoint clear_watchpoint;
debug_nub_set_signal_masks set_signal_masks;
debug_nub_get_signal_masks get_signal_masks;
debug_nub_set_signal_handler set_signal_handler;
debug_nub_get_signal_handler get_signal_handler;
debug_nub_start_profiler start_profiler;
debug_nub_stop_profiler stop_profiler;
debug_nub_write_core_file write_core_file;
} debug_nub_message_data;
// #pragma mark -
// #pragma mark ----- messages to the debugger -----
// first member of all debugger messages -- not a message by itself
typedef struct
{
thread_id thread; // the thread being the event origin
team_id team; // the thread's team
port_id nub_port; // port to debug nub for this team (only set
// for synchronous messages)
} debug_origin;
// B_DEBUGGER_MESSAGE_THREAD_DEBUGGED
typedef struct
{
debug_origin origin;
} debug_thread_debugged;
// B_DEBUGGER_MESSAGE_DEBUGGER_CALL
typedef struct
{
debug_origin origin;
void *message; // address of the message passed to
// debugger()
} debug_debugger_call;
// B_DEBUGGER_MESSAGE_BREAKPOINT_HIT
typedef struct
{
debug_origin origin;
debug_cpu_state cpu_state; // cpu state
} debug_breakpoint_hit;
// B_DEBUGGER_MESSAGE_WATCHPOINT_HIT
typedef struct
{
debug_origin origin;
debug_cpu_state cpu_state; // cpu state
} debug_watchpoint_hit;
// B_DEBUGGER_MESSAGE_SINGLE_STEP
typedef struct
{
debug_origin origin;
debug_cpu_state cpu_state; // cpu state
} debug_single_step;
// B_DEBUGGER_MESSAGE_PRE_SYSCALL
typedef struct
{
debug_origin origin;
uint32 syscall; // the syscall number
uint8 args[128]; // syscall arguments
} debug_pre_syscall;
// B_DEBUGGER_MESSAGE_POST_SYSCALL
typedef struct
{
debug_origin origin;
bigtime_t start_time; // time of syscall start
bigtime_t end_time; // time of syscall completion
uint64 return_value; // the syscall's return value
uint32 syscall; // the syscall number
uint8 args[128]; // syscall arguments
} debug_post_syscall;
// B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED
typedef struct
{
debug_origin origin;
int signal; // the signal
struct haiku_sigaction handler; // the signal handler
bool deadly; // true, if handling the signal will kill
// the team
} debug_signal_received;
// B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED
typedef struct
{
debug_origin origin;
debug_exception_type exception; // the exception
int signal; // the signal that will be sent,
// when the thread continues
// normally
} debug_exception_occurred;
// B_DEBUGGER_MESSAGE_TEAM_CREATED
typedef struct
{
debug_origin origin;
team_id new_team; // the newly created team
} debug_team_created;
// B_DEBUGGER_MESSAGE_TEAM_DELETED
typedef struct
{
debug_origin origin; // thread is < 0, team is the deleted team
// (asynchronous message)
} debug_team_deleted;
// B_DEBUGGER_MESSAGE_TEAM_EXEC
typedef struct
{
debug_origin origin;
int32 image_event; // number of the image event
} debug_team_exec;
// B_DEBUGGER_MESSAGE_THREAD_CREATED
typedef struct
{
debug_origin origin; // the thread that created the new thread
team_id new_thread; // the newly created thread
} debug_thread_created;
// B_DEBUGGER_MESSAGE_THREAD_DELETED
typedef struct
{
debug_origin origin; // the deleted thread (asynchronous message)
} debug_thread_deleted;
// B_DEBUGGER_MESSAGE_IMAGE_CREATED
typedef struct
{
debug_origin origin;
haiku_image_info info; // info for the image
int32 image_event; // number of the image event
} debug_image_created;
// B_DEBUGGER_MESSAGE_IMAGE_DELETED
typedef struct
{
debug_origin origin;
haiku_image_info info; // info for the image
int32 image_event; // number of the image event
} debug_image_deleted;
// B_DEBUGGER_MESSAGE_PROFILER_UPDATE
typedef struct
{
debug_origin origin;
int32 image_event; // number of the last image event; all
// samples were recorded after this
// event and before the next one
int32 stack_depth; // number of return addresses per tick
int32 sample_count; // number of samples in the buffer
int32 dropped_ticks; // number of ticks that had been
// dropped, since the buffer was full
bool variable_stack_depth;
// the number of samples per hit is
// variable, i.e. the format for the
// samples of a hit in the buffer is
// <n> <sample 1> ... <sample n>
// instead of
// <sample 1> ... <sample stack_depth>
bool stopped; // if true, the thread is no longer
// being profiled
} debug_profiler_update;
// B_DEBUGGER_MESSAGE_HANDED_OVER
typedef struct
{
debug_origin origin; // thread is < 0, team is the deleted team
// (asynchronous message)
team_id debugger; // the new debugger
port_id debugger_port; // the port the new debugger uses
thread_id causing_thread; // the thread that caused entering the
// debugger in the first place, -1 if the
// debugger wasn't attached automatically
} debug_handed_over;
// union of all messages structures sent to the debugger
typedef union
{
debug_thread_debugged thread_debugged;
debug_debugger_call debugger_call;
debug_breakpoint_hit breakpoint_hit;
debug_watchpoint_hit watchpoint_hit;
debug_single_step single_step;
debug_pre_syscall pre_syscall;
debug_post_syscall post_syscall;
debug_signal_received signal_received;
debug_exception_occurred exception_occurred;
debug_team_created team_created;
debug_team_deleted team_deleted;
debug_team_exec team_exec;
debug_thread_created thread_created;
debug_thread_deleted thread_deleted;
debug_image_created image_created;
debug_image_deleted image_deleted;
debug_profiler_update profiler_update;
debug_handed_over handed_over;
debug_origin origin; // for convenience (no real message)
} debug_debugger_message_data;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _DEBUGGER_H