fee7b45292259a4c4de4e240dd68b8fa9f45817a
[barrelfish] / lib / barrelfish / debug.c
1 /**
2  * \file
3  * \brief Debugging functions
4  */
5
6 /*
7  * Copyright (c) 2008-2011, ETH Zurich.
8  * Copyright (c) 2015, 2016 Hewlett Packard Enterprise Development LP.
9  * All rights reserved.
10  *
11  * This file is distributed under the terms in the attached LICENSE file.
12  * If you do not find this file, copies can be found by writing to:
13  * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
14  */
15
16 #include <stdio.h>
17 #include <barrelfish/barrelfish.h>
18 #include <barrelfish/caddr.h>
19 #include <barrelfish/debug.h>
20 #include <barrelfish/sys_debug.h>
21 #include <barrelfish/dispatch.h>
22 #include <if/monitor_blocking_rpcclient_defs.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <inttypes.h>
27 #include <barrelfish_kpi/dispatcher_shared.h>
28
29 #define DISP_MEMORY_SIZE            1024 // size of memory dump in bytes
30
31 /**
32  * \brief Print a message and abort.
33  *
34  * Something irrecoverably bad happened. Print a panic message, then abort.
35  */
36 void user_panic_fn(const char *file, const char *func, int line,
37                    const char *msg, ...)
38 {
39     va_list ap;
40     char msg_str[128];
41     //int msg_str_cc;
42     va_start(ap, msg);
43     //msg_str_cc =
44         vsnprintf(msg_str, sizeof(msg_str), msg, ap);
45     va_end(ap);
46
47     char str[256];
48     //int strcc =
49         snprintf(str, sizeof(str), "%.*s.%u in %s() %s:%d\n%s\n",
50                      DISP_NAME_LEN, disp_name(), disp_get_core_id(),
51                      func, file, line, msg_str);
52     sys_print(str, sizeof(str));
53
54     abort();
55 }
56
57 errval_t debug_cap_identify(struct capref cap, struct capability *ret)
58 {
59     errval_t err, msgerr;
60
61     if (get_cap_addr(cap) == 0) {
62         return SYS_ERR_CAP_NOT_FOUND;
63     }
64
65     union {
66         monitor_blocking_caprep_t caprep;
67         struct capability capability;
68     } u;
69
70     struct monitor_blocking_rpc_client *r = get_monitor_blocking_rpc_client();
71     if (!r) {
72         return LIB_ERR_MONITOR_RPC_NULL;
73     }
74     err = r->vtbl.cap_identify(r, cap, &msgerr, &u.caprep);
75     if (err_is_fail(err)){
76         return err;
77     } else if (err_is_fail(msgerr)) {
78         return msgerr;
79     }
80
81     assert(ret != NULL);
82     *ret = u.capability;
83
84     return msgerr;
85 }
86
87 /**
88  * \brief Enable fine-grained tracing of cap operations on address range
89  * [start_addr, start_addr+size)
90  * \arg types enable tracing for given set of ORed ObjType_s
91  * \arg start_addr start of region to trace for
92  * \arg size size of region to trace for
93  */
94 errval_t debug_cap_trace_ctrl(uintptr_t types, genpaddr_t start_addr, gensize_t size)
95 {
96     if (types) {
97         printf("enabling pmem tracing: 0x%"PRIxGENPADDR"--0x%"PRIxGENPADDR
98                " for types 0x%"PRIxPTR"\n",
99                start_addr, start_addr+size, types);
100     }
101     return sys_debug_cap_trace_ctrl(types, start_addr, size);
102 }
103
104 /**
105  * \brief Dump own hw page tables
106  */
107 errval_t debug_dump_hw_ptables(void)
108 {
109     return invoke_dispatcher_dump_ptables(cap_dispatcher);
110 }
111
112 void debug_printf(const char *fmt, ...)
113 {
114     struct thread *me = thread_self();
115     va_list argptr;
116     char id[32] = "-";
117     char str[256];
118     size_t len;
119
120     if (me)
121         snprintf(id, sizeof(id), "%"PRIuPTR, thread_get_id(me));
122     len = snprintf(str, sizeof(str), "\033[34m%.*s.\033[31m%u.%s\033[0m: ",
123                    DISP_NAME_LEN, disp_name(), disp_get_core_id(), id);
124     if (len < sizeof(str)) {
125         va_start(argptr, fmt);
126         vsnprintf(str + len, sizeof(str) - len, fmt, argptr);
127         va_end(argptr);
128     }
129     sys_print(str, sizeof(str));
130 }
131
132 /**
133  * \brief Function to do the actual printing based on the type of capability
134  */
135 STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
136 int debug_print_cap(char *buf, size_t len, struct capability *cap)
137 {
138     switch (cap->type) {
139     case ObjType_PhysAddr:
140         return snprintf(buf, len,
141                         "physical address range cap (0x%" PRIxGENPADDR ":0x%" PRIuGENSIZE ")",
142                         cap->u.physaddr.base, cap->u.physaddr.bytes);
143
144     case ObjType_RAM:
145         return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":0x%" PRIuGENSIZE ")",
146                         cap->u.ram.base, cap->u.ram.bytes);
147
148     case ObjType_CNode: {
149         int ret = snprintf(buf, len, "CNode cap "
150                            "(bits %u, rights mask 0x%" PRIxCAPRIGHTS ")",
151                            cap->u.cnode.bits, cap->u.cnode.rightsmask);
152         if (cap->u.cnode.guard_size != 0 && ret < len) {
153             ret += snprintf(&buf[ret], len - ret, " (guard 0x%" PRIxCADDR ":%u)",
154                             cap->u.cnode.guard, cap->u.cnode.guard_size);
155         }
156         return ret;
157     }
158
159     case ObjType_Dispatcher:
160         return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
161
162     case ObjType_Frame:
163         return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":0x%" PRIuGENSIZE ")",
164                         cap->u.frame.base, cap->u.frame.bytes);
165
166     case ObjType_DevFrame:
167         return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":%" PRIuGENSIZE ")",
168                         cap->u.frame.base, cap->u.devframe.bytes);
169
170     case ObjType_VNode_ARM_l1:
171         return snprintf(buf, len, "ARM L1 table at 0x%" PRIxGENPADDR,
172                         cap->u.vnode_arm_l1.base);
173
174     case ObjType_VNode_ARM_l2:
175         return snprintf(buf, len, "ARM L2 table at 0x%" PRIxGENPADDR,
176                         cap->u.vnode_arm_l2.base);
177
178     case ObjType_VNode_AARCH64_l0:
179         return snprintf(buf, len, "AARCH64 L0 table at 0x%" PRIxGENPADDR,
180                         cap->u.vnode_aarch64_l0.base);
181
182     case ObjType_VNode_AARCH64_l1:
183         return snprintf(buf, len, "AARCH64 L1 table at 0x%" PRIxGENPADDR,
184                         cap->u.vnode_aarch64_l1.base);
185
186     case ObjType_VNode_AARCH64_l2:
187         return snprintf(buf, len, "AARCH64 L2 table at 0x%" PRIxGENPADDR,
188                         cap->u.vnode_aarch64_l2.base);
189
190     case ObjType_VNode_AARCH64_l3:
191         return snprintf(buf, len, "AARCH64 L3 table at 0x%" PRIxGENPADDR,
192                         cap->u.vnode_aarch64_l3.base);
193
194     case ObjType_VNode_x86_32_ptable:
195         return snprintf(buf, len, "x86_32 Page table at 0x%" PRIxGENPADDR,
196                         cap->u.vnode_x86_32_ptable.base);
197
198     case ObjType_VNode_x86_32_pdir:
199         return snprintf(buf, len, "x86_32 Page directory at 0x%" PRIxGENPADDR,
200                         cap->u.vnode_x86_32_pdir.base);
201
202     case ObjType_VNode_x86_32_pdpt:
203         return snprintf(buf, len, "x86_32 PDPT at 0x%" PRIxGENPADDR,
204                         cap->u.vnode_x86_32_pdpt.base);
205
206     case ObjType_VNode_x86_64_ptable:
207         return snprintf(buf, len, "x86_64 Page table at 0x%" PRIxGENPADDR,
208                         cap->u.vnode_x86_64_ptable.base);
209
210     case ObjType_VNode_x86_64_pdir:
211         return snprintf(buf, len, "x86_64 Page directory at 0x%" PRIxGENPADDR,
212                         cap->u.vnode_x86_64_pdir.base);
213
214     case ObjType_VNode_x86_64_pdpt:
215         return snprintf(buf, len, "x86_64 PDPT at 0x%" PRIxGENPADDR,
216                         cap->u.vnode_x86_64_pdpt.base);
217
218     case ObjType_VNode_x86_64_pml4:
219         return snprintf(buf, len, "x86_64 PML4 at 0x%" PRIxGENPADDR,
220                         cap->u.vnode_x86_64_pml4.base);
221
222     case ObjType_Frame_Mapping:
223         return snprintf(buf, len, "Frame Mapping (Frame cap @0x%p, "
224                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
225                                   cap->u.frame_mapping.frame,
226                                   cap->u.frame_mapping.pte,
227                                   cap->u.frame_mapping.pte_count);
228
229     case ObjType_DevFrame_Mapping:
230         return snprintf(buf, len, "DevFrame Mapping (DevFrame cap @0x%p, "
231                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
232                                   cap->u.devframe_mapping.frame,
233                                   cap->u.devframe_mapping.pte,
234                                   cap->u.devframe_mapping.pte_count);
235
236     case ObjType_VNode_x86_64_pml4_Mapping:
237         return snprintf(buf, len, "x86_64 PML4 Mapping (x86_64 PML4 cap @0x%p, "
238                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
239                                   cap->u.vnode_x86_64_pml4_mapping.frame,
240                                   cap->u.vnode_x86_64_pml4_mapping.pte,
241                                   cap->u.vnode_x86_64_pml4_mapping.pte_count);
242
243     case ObjType_VNode_x86_64_pdpt_Mapping:
244         return snprintf(buf, len, "x86_64 PDPT Mapping (x86_64 PDPT cap @0x%p, "
245                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
246                                   cap->u.vnode_x86_64_pdpt_mapping.frame,
247                                   cap->u.vnode_x86_64_pdpt_mapping.pte,
248                                   cap->u.vnode_x86_64_pdpt_mapping.pte_count);
249
250     case ObjType_VNode_x86_64_pdir_Mapping:
251         return snprintf(buf, len, "x86_64 PDIR Mapping (x86_64 PDIR cap @0x%p, "
252                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
253                                   cap->u.vnode_x86_64_pdir_mapping.frame,
254                                   cap->u.vnode_x86_64_pdir_mapping.pte,
255                                   cap->u.vnode_x86_64_pdir_mapping.pte_count);
256
257     case ObjType_VNode_x86_64_ptable_Mapping:
258         return snprintf(buf, len, "x86_64 PTABLE Mapping (x86_64 PTABLE cap @0x%p, "
259                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
260                                   cap->u.vnode_x86_64_ptable_mapping.frame,
261                                   cap->u.vnode_x86_64_ptable_mapping.pte,
262                                   cap->u.vnode_x86_64_ptable_mapping.pte_count);
263
264     case ObjType_VNode_x86_32_pdpt_Mapping:
265         return snprintf(buf, len, "x86_32 PDPT Mapping (x86_32 PDPT cap @0x%p, "
266                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
267                                   cap->u.vnode_x86_32_pdpt_mapping.frame,
268                                   cap->u.vnode_x86_32_pdpt_mapping.pte,
269                                   cap->u.vnode_x86_32_pdpt_mapping.pte_count);
270
271     case ObjType_VNode_x86_32_pdir_Mapping:
272         return snprintf(buf, len, "x86_32 PDIR Mapping (x86_32 PDIR cap @0x%p, "
273                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
274                                   cap->u.vnode_x86_32_pdir_mapping.frame,
275                                   cap->u.vnode_x86_32_pdir_mapping.pte,
276                                   cap->u.vnode_x86_32_pdir_mapping.pte_count);
277
278     case ObjType_VNode_x86_32_ptable_Mapping:
279         return snprintf(buf, len, "x86_32 PTABLE Mapping (x86_32 PTABLE cap @0x%p, "
280                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
281                                   cap->u.vnode_x86_32_ptable_mapping.frame,
282                                   cap->u.vnode_x86_32_ptable_mapping.pte,
283                                   cap->u.vnode_x86_32_ptable_mapping.pte_count);
284
285     case ObjType_VNode_ARM_l1_Mapping:
286         return snprintf(buf, len, "ARM l1 Mapping (ARM l1 cap @0x%p, "
287                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
288                                   cap->u.vnode_arm_l1_mapping.frame,
289                                   cap->u.vnode_arm_l1_mapping.pte,
290                                   cap->u.vnode_arm_l1_mapping.pte_count);
291
292     case ObjType_VNode_ARM_l2_Mapping:
293         return snprintf(buf, len, "ARM l2 Mapping (ARM l2 cap @0x%p, "
294                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
295                                   cap->u.vnode_arm_l2_mapping.frame,
296                                   cap->u.vnode_arm_l2_mapping.pte,
297                                   cap->u.vnode_arm_l2_mapping.pte_count);
298
299     case ObjType_VNode_AARCH64_l0_Mapping:
300         return snprintf(buf, len, "AARCH64 l0 Mapping (AARCH64 l0 cap @0x%p, "
301                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
302                                   cap->u.vnode_aarch64_l0_mapping.frame,
303                                   cap->u.vnode_aarch64_l0_mapping.pte,
304                                   cap->u.vnode_aarch64_l0_mapping.pte_count);
305
306     case ObjType_VNode_AARCH64_l1_Mapping:
307         return snprintf(buf, len, "AARCH64 l1 Mapping (AARCH64 l1 cap @0x%p, "
308                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
309                                   cap->u.vnode_aarch64_l1_mapping.frame,
310                                   cap->u.vnode_aarch64_l1_mapping.pte,
311                                   cap->u.vnode_aarch64_l1_mapping.pte_count);
312
313     case ObjType_VNode_AARCH64_l2_Mapping:
314         return snprintf(buf, len, "AARCH64 l2 Mapping (AARCH64 l2 cap @0x%p, "
315                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
316                                   cap->u.vnode_aarch64_l2_mapping.frame,
317                                   cap->u.vnode_aarch64_l2_mapping.pte,
318                                   cap->u.vnode_aarch64_l2_mapping.pte_count);
319
320     case ObjType_VNode_AARCH64_l3_Mapping:
321         return snprintf(buf, len, "AARCH64 l3 Mapping (AARCH64 l3 cap @0x%p, "
322                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
323                                   cap->u.vnode_aarch64_l3_mapping.frame,
324                                   cap->u.vnode_aarch64_l3_mapping.pte,
325                                   cap->u.vnode_aarch64_l3_mapping.pte_count);
326
327
328     case ObjType_IRQTable:
329         return snprintf(buf, len, "IRQTable cap");
330
331     case ObjType_IRQDest:
332         return snprintf(buf, len, "IRQDest cap (vec: %"PRIu64", ctrl: %"PRIu64")",
333                 cap->u.irqdest.vector, cap->u.irqdest.controller);
334
335     case ObjType_EndPoint:
336         return snprintf(buf, len, "EndPoint cap (disp %p offset 0x%" PRIxLVADDR ")",
337                         cap->u.endpoint.listener, cap->u.endpoint.epoffset);
338
339     case ObjType_IO:
340         return snprintf(buf, len, "IO cap (0x%hx-0x%hx)",
341                         cap->u.io.start, cap->u.io.end);
342
343     case ObjType_Kernel:
344         return snprintf(buf, len, "Kernel cap");
345
346     case ObjType_KernelControlBlock:
347         return snprintf(buf, len, "Kernel control block cap");
348
349     case ObjType_ID:
350         return snprintf(buf, len, "ID capability (coreid 0x%" PRIxCOREID
351                         " core_local_id 0x%" PRIx32 ")", cap->u.id.coreid,
352                         cap->u.id.core_local_id);
353
354     case ObjType_PerfMon:
355         return snprintf(buf, len, "PerfMon cap");
356
357     case ObjType_Null:
358         return snprintf(buf, len, "Null cap (empty slot)");
359
360     default:
361         return snprintf(buf, len, "UNKNOWN TYPE! (%d)", cap->type);
362     }
363 }
364
365 int debug_print_cap_at_capref(char *buf, size_t len, struct capref cap)
366 {
367     struct capability capability;
368     errval_t err;
369
370     if (capref_is_null(cap)) {
371         return snprintf(buf, len, "(null cap)");
372     }
373
374     err = debug_cap_identify(cap, &capability);
375     if (err_is_fail(err)) {
376         return snprintf(buf, len, "(ERROR identifying cap!)");
377     } else {
378         return debug_print_cap(buf, len, &capability);
379     }
380 }
381
382 /**
383  * \brief Walk the cspace printing all non-null capabilities
384  *
385  * \param cnode         cnode to walk
386  * \param level         depth in the cspace
387  *
388  * \bug assumes guards are always zero
389  */
390 static void walk_cspace(struct cnoderef cnode, uint8_t level)
391 {
392     struct capability cap;
393     errval_t err;
394
395     struct capref pos = {
396         .cnode = cnode, .slot = 0
397     };
398
399     // If too many bits resolved, return
400     if (pos.cnode.address_bits + pos.cnode.guard_size + pos.cnode.size_bits
401         > CPTR_BITS) {
402         return;
403     }
404
405     // Walk through all the slots in the CNode
406     for (pos.slot = 0; pos.slot < (((capaddr_t)1) << cnode.size_bits); pos.slot++) {
407         // Get cap data
408         err = debug_cap_identify(pos, &cap);
409
410         // If cap type was Null, kernel returns error
411         if (err_no(err) == SYS_ERR_IDENTIFY_LOOKUP ||
412             err_no(err) == SYS_ERR_CAP_NOT_FOUND ||
413             err_no(err) == SYS_ERR_LMP_CAPTRANSFER_SRC_LOOKUP) {
414             continue;
415         } else if (err_is_fail(err)) {
416             DEBUG_ERR(err, "debug_cap_identify failed");
417             return;
418         }
419
420         char buf[256];
421         size_t prpos = 0;
422
423         // Print the stats for the child slot
424         for(int i = 0; i < level; i++) {
425             prpos += snprintf(&buf[prpos], sizeof(buf) - prpos, "  ");
426             assert(prpos < sizeof(buf));
427         }
428         prpos += snprintf(&buf[prpos], sizeof(buf) - prpos,
429                           "slot %" PRIuCADDR " caddr 0x%" PRIxCADDR " (%u bits) is a ",
430                           pos.slot, get_cap_addr(pos), get_cap_valid_bits(pos));
431         assert(prpos < sizeof(buf));
432         prpos += debug_print_cap(&buf[prpos], sizeof(buf) - prpos, &cap);
433         assert(prpos < sizeof(buf));
434         debug_printf("%s\n", buf);
435
436         // If CNode type, descend into it
437         if (cap.type == ObjType_CNode) {
438             struct cnoderef childcn = {
439                 .address = get_cap_addr(pos),
440                 .address_bits = get_cap_valid_bits(pos),
441                 .size_bits = cap.u.cnode.bits,
442                 .guard_size = cap.u.cnode.guard_size,
443             };
444             walk_cspace(childcn, level + 1);
445         }
446     }
447 }
448
449 /**
450  * \brief Dump an arbitrary cspace, given the root
451  */
452 void debug_cspace(struct capref root)
453 {
454     struct capability cap;
455
456     /* find out size of root cnode */
457     errval_t err = debug_cap_identify(root, &cap);
458     assert(err_is_ok(err));
459
460     struct cnoderef cnode = {
461         .address = get_cap_addr(root),
462         .address_bits = get_cap_valid_bits(root),
463         .size_bits = cap.u.cnode.bits,
464         .guard_size = cap.u.cnode.guard_size,
465     };
466
467     walk_cspace(cnode, 0);
468 }
469
470 void debug_my_cspace(void)
471 {
472     // XXX: Assume my root CNode has a size of #DEFAULT_CNODE_BITS
473     struct cnoderef cnode = {
474         .address = 0,
475         .address_bits = 0,
476         .size_bits = DEFAULT_CNODE_BITS,
477         .guard_size = 0,
478     };
479
480     walk_cspace(cnode, 0);
481 }
482
483 int debug_print_capref(char *buf, size_t len, struct capref cap)
484 {
485     return snprintf(buf, len, "CNode addr 0x%08" PRIxCADDR
486                               ", vbits = %d, slot %" PRIuCADDR ", vbits = %d",
487                     get_cnode_addr(cap),  get_cnode_valid_bits(cap), cap.slot,
488                     get_cap_valid_bits(cap));
489 }
490
491 void debug_dump_mem(lvaddr_t start_addr, lvaddr_t end_addr, lvaddr_t point)
492 {
493     debug_printf("Dumping memory in range 0x%" PRIxLVADDR
494                  " to 0x%" PRIxLVADDR ":\n",
495                  start_addr, end_addr);
496
497     for (uintptr_t *p = (void *)start_addr; (uintptr_t)p < end_addr; p++) {
498         uint8_t *bytes = (void *)p;
499         char buf[32];
500         size_t bufpos = 0;
501         for (int i = 0; i < sizeof(uintptr_t); i++) {
502             bufpos += snprintf(&buf[bufpos], sizeof(buf) - bufpos, "%02x ", bytes[i]);
503             assert(bufpos < sizeof(buf));
504         }
505         debug_printf("%p: %.*s %*" PRIxPTR "%s\n", p, (int)sizeof(buf), buf,
506                      (int)sizeof(uintptr_t) * 2, *p,
507                      p == (uintptr_t *)point ? " <== We are here" : "");
508     }
509 }
510
511 void debug_dump_mem_around_addr(lvaddr_t addr)
512 {
513     /* lvaddr_t page_aligned_addr = ROUND_DOWN(addr, BASE_PAGE_SIZE); */
514     lvaddr_t start_addr = ROUND_DOWN(addr - DISP_MEMORY_SIZE/2, sizeof(uintptr_t));
515     lvaddr_t end_addr = ROUND_UP(addr + DISP_MEMORY_SIZE/2, sizeof(uintptr_t));
516
517     /* if (start_addr < page_aligned_addr) { */
518     /*     start_addr = page_aligned_addr; */
519     /* } */
520     /* if (end_addr > page_aligned_addr + BASE_PAGE_SIZE) { */
521     /*     end_addr = page_aligned_addr + BASE_PAGE_SIZE; */
522     /* } */
523
524     debug_dump_mem(start_addr, end_addr, addr);
525 }
526
527 void debug_err(const char *file, const char *func, int line, errval_t err,
528                const char *msg, ...)
529 {
530     va_list ap;
531
532     char str[256];
533     char *leader = (err == 0) ? "SUCCESS" : "ERROR";
534     //int strcc =
535         snprintf(str, sizeof(str), "%s: %.*s.%u in %s() %s:%d\n%s: ",
536                      leader, DISP_NAME_LEN, disp_name(), disp_get_core_id(),
537                      func, file, line, leader);
538     sys_print(str, sizeof(str));
539
540     if (msg != NULL) {
541         va_start(ap, msg);
542         //int strcc2 =
543             vsnprintf(str, sizeof(str), msg, ap);
544         va_end(ap);
545         sys_print(str, sizeof(str));
546     }
547     sys_print("\n", 1);
548
549     if (err != 0) {
550         err_print_calltrace(err);
551     }
552 }
553
554 bool debug_notify_syscall = false;
555
556 void debug_control_plane_forbidden(void);
557 void debug_control_plane_forbidden(void)
558 {
559     debug_notify_syscall = true;
560 }