Fabcoin Core  0.16.2
P2P Digital Currency
debugbreak.h
Go to the documentation of this file.
1 /* Copyright (c) 2013, Scott Tsai
2  *
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef DEBUG_BREAK_H
28 #define DEBUG_BREAK_H
29 
30 #if defined(_MSC_VER) || defined(__MINGW32__)
31 
32 #define debug_break __debugbreak
33 
34 #else
35 
36 #include <signal.h>
37 #include <unistd.h>
38 #include <sys/syscall.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 enum {
45  /* gcc optimizers consider code after __builtin_trap() dead.
46  * Making __builtin_trap() unsuitable for breaking into the debugger */
48 };
49 
50 #if defined(__i386__) || defined(__x86_64__)
51 enum { HAVE_TRAP_INSTRUCTION = 1, };
52 __attribute__((gnu_inline, always_inline))
53 static void __inline__ trap_instruction(void)
54 {
55  __asm__ volatile("int $0x03");
56 }
57 #elif defined(__thumb__)
58 enum { HAVE_TRAP_INSTRUCTION = 1, };
59 /* FIXME: handle __THUMB_INTERWORK__ */
60 __attribute__((gnu_inline, always_inline))
61 static void __inline__ trap_instruction(void)
62 {
63  /* See 'arm-linux-tdep.c' in GDB source.
64  * Both instruction sequences below works. */
65 #if 1
66  /* 'eabi_linux_thumb_le_breakpoint' */
67  __asm__ volatile(".inst 0xde01");
68 #else
69  /* 'eabi_linux_thumb2_le_breakpoint' */
70  __asm__ volatile(".inst.w 0xf7f0a000");
71 #endif
72 
73  /* Known problem:
74  * After a breakpoint hit, can't stepi, step, or continue in GDB.
75  * 'step' stuck on the same instruction.
76  *
77  * Workaround: a new GDB command,
78  * 'debugbreak-step' is defined in debugbreak-gdb.py
79  * that does:
80  * (gdb) set $instruction_len = 2
81  * (gdb) tbreak *($pc + $instruction_len)
82  * (gdb) jump *($pc + $instruction_len)
83  */
84 }
85 #elif defined(__arm__) && !defined(__thumb__)
86 enum { HAVE_TRAP_INSTRUCTION = 1, };
87 __attribute__((gnu_inline, always_inline))
88 static void __inline__ trap_instruction(void)
89 {
90  /* See 'arm-linux-tdep.c' in GDB source,
91  * 'eabi_linux_arm_le_breakpoint' */
92  __asm__ volatile(".inst 0xe7f001f0");
93  /* Has same known problem and workaround
94  * as Thumb mode */
95 }
96 #else
97 enum { HAVE_TRAP_INSTRUCTION = 0, };
98 #endif
99 
100 __attribute__((gnu_inline, always_inline))
101 static void __inline__ debug_break(void)
102 {
103 #ifdef FASC_BUILD
104  __builtin_trap();
105 #else
106  if (HAVE_TRAP_INSTRUCTION) {
107 #if defined(ETH_EMSCRIPTEN)
108  asm("debugger");
109 #else
110  trap_instruction();
111 #endif
113  /* raises SIGILL on Linux x86{,-64}, to continue in gdb:
114  * (gdb) handle SIGILL stop nopass
115  * */
116  __builtin_trap();
117  } else {
118  raise(SIGTRAP);
119  }
120 #endif
121 }
122 
123 #ifdef __cplusplus
124 }
125 #endif
126 
127 #endif
128 
129 #endif
__attribute__((gnu_inline, always_inline)) static void __inline__ debug_break(void)
Definition: debugbreak.h:100