pax_global_header00006660000000000000000000000064140076333350014516gustar00rootroot0000000000000052 comment=56b6b8f20f75f5d938ac33adbfb3d39c91261eb4 debugbreak-1.0/000077500000000000000000000000001400763333500134515ustar00rootroot00000000000000debugbreak-1.0/.gitignore000066400000000000000000000001251400763333500154370ustar00rootroot00000000000000*.o fib core core.* cscope.out tags .gdb_history test/trap test/break test/break-c++ debugbreak-1.0/COPYING000066400000000000000000000024271400763333500145110ustar00rootroot00000000000000Copyright (c) 2011-2016, Scott Tsai All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. debugbreak-1.0/GNUmakefile000066400000000000000000000010021400763333500155140ustar00rootroot00000000000000CFLAGS := -Os -Wall -g CXXFLAGS := $(CFLAGS) PROGRAMS := $(basename $(wildcard *.c test/*.c test/*.cc *.S)) .PHONY: all clean all: $(PROGRAMS) clean: rm -f $(PROGRAMS) cscope.out tags %: %.S $(CC) $(CFLAGS) -nostdlib $< -o $@ # Not using builtin rules due to debugbreak.h dependency %: %.c $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ %: %.cc $(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@ test/%: CFLAGS +=-I. test/%: CXXFLAGS +=-I. $(PROGRAMS): debugbreak.h GDB ?= gdb .PHONY: gdb gdb: $(GDB) -q -x debugbreak-gdb.py debugbreak-1.0/HOW-TO-USE-DEBUGBREAK-GDB-PY.md000066400000000000000000000016251400763333500177170ustar00rootroot00000000000000# How to use `debugbreak-gdb.py` Just add `-x debugbreak-gdb.py` to your usual GDB invocation or add `source debugbreak-gdb.py` to your `$HOME/.gdbinit`. Here's a sample session: ``` $ cd debugbreak $ make $ gdb -q -x debugbreak-gdb.py test/break Reading symbols from test/break...done. (gdb) set disassemble-next-line 1 (gdb) run Starting program: /home/fedora/debugbreak/test/break Program received signal SIGTRAP, Trace/breakpoint trap. main () at test/break.c:6 6 debug_break(); Program received signal SIGTRAP, Trace/breakpoint trap. main () at test/break.c:6 6 debug_break(); (gdb) debugbreak-step 7 printf("hello world\n"); (gdb) debugbreak-continue hello world [Inferior 1 (process 12533) exited normally] (gdb) ``` On ARM and POWER, trying to use `step` or `stepi` in place of `debugbreak-step` in the sesion above wouldn't have worked as execution would be stock on the breakpoint instruction. debugbreak-1.0/README.md000066400000000000000000000125561400763333500147410ustar00rootroot00000000000000# Debug Break [debugbreak.h](https://github.com/scottt/debugbreak/blob/master/debugbreak.h) allows you to put breakpoints in your C/C++ code with a call to **debug_break()**: ```C #include #include "debugbreak.h" int main() { debug_break(); /* will break into debugger */ printf("hello world\n"); return 0; } ``` * Include one header file and insert calls to `debug_break()` in the code where you wish to break into the debugger. * Supports GCC, Clang and MSVC. * Works well on ARM, AArch64, i686, x86-64, POWER and has a fallback code path for other architectures. * Works like the **DebugBreak()** fuction provided by [Windows](http://msdn.microsoft.com/en-us/library/ea9yy3ey.aspx) and [QNX](http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/lib_ref/d/debugbreak.html). **License**: the very permissive [2-Clause BSD](https://github.com/scottt/debugbreak/blob/master/COPYING). Known Problem: if continuing execution after a debugbreak breakpoint hit doesn't work (e.g. on ARM or POWER), see [HOW-TO-USE-DEBUGBREAK-GDB-PY.md](HOW-TO-USE-DEBUGBREAK-GDB-PY.md) for a workaround. Implementation Notes ================================ The requirements for the **debug_break()** function are: * Act as a compiler code motion barrier * Don't cause the compiler optimizers to think the code following it can be removed * Trigger a software breakpoint hit when executed (e.g. **SIGTRAP** on Linux) * GDB commands like **continue**, **next**, **step**, **stepi** must work after a **debug_break()** hit Ideally, both GCC and Clang would provide a **__builtin_debugtrap()** that satisfies the above on all architectures and operating systems. Unfortunately, that is not the case (yet). GCC's [__builtin_trap()](http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005ftrap-3278) causes the optimizers to think the code follwing can be removed ([test/trap.c](https://github.com/scottt/debugbreak/blob/master/test/trap.c)): ```C #include int main() { __builtin_trap(); printf("hello world\n"); return 0; } ``` compiles to: ``` main 0x0000000000400390 <+0>: 0f 0b ud2 ``` Notice how the call to `printf()` is not present in the assembly output. Further, on i386 / x86-64 **__builtin_trap()** generates an **ud2** instruction which triggers **SIGILL** instead of **SIGTRAP**. This makes it necessary to change GDB's default behavior on **SIGILL** to not terminate the process being debugged: ``` (gdb) handle SIGILL stop nopass ``` Even after this, continuing execution in GDB doesn't work well on some GCC, GDB combinations. See [GCC Bugzilla 84595](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84595). On ARM, **__builtin_trap()** generates a call to **abort()**, making it even less suitable. **debug_break()** generates an **int3** instruction on i386 / x86-64 ([test/break.c](https://github.com/scottt/debugbreak/blob/master/test/break.c)): ```C #include #include "debugbreak.h" int main() { debug_break(); printf("hello world\n"); return 0; } ``` compiles to: ``` main 0x00000000004003d0 <+0>: 50 push %rax 0x00000000004003d1 <+1>: cc int3 0x00000000004003d2 <+2>: bf a0 05 40 00 mov $0x4005a0,%edi 0x00000000004003d7 <+7>: e8 d4 ff ff ff callq 0x4003b0 0x00000000004003dc <+12>: 31 c0 xor %eax,%eax 0x00000000004003de <+14>: 5a pop %rdx 0x00000000004003df <+15>: c3 retq ``` which correctly trigges **SIGTRAP** and single-stepping in GDB after a **debug_break()** hit works well. Clang / LLVM also has a **__builtin_trap()** that generates **ud2** but further provides **__builtin_debugtrap()** that generates **int3** on i386 / x86-64 ([original LLVM intrinsic](http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20120507/142621.html), [further fixes](https://reviews.llvm.org/rL166300#96cef7d3), [Clang builtin support](https://reviews.llvm.org/rL166298)). On ARM, **debug_break()** generates **.inst 0xe7f001f0** in ARM mode and **.inst 0xde01** in Thumb mode which correctly triggers **SIGTRAP** on Linux. Unfortunately, stepping in GDB after a **debug_break()** hit doesn't work and requires a workaround like: ``` (gdb) set $l = 2 (gdb) tbreak *($pc + $l) (gdb) jump *($pc + $l) (gdb) # Change $l from 2 to 4 for ARM mode ``` to jump over the instruction. A new GDB command, **debugbreak-step**, is defined in [debugbreak-gdb.py](https://github.com/scottt/debugbreak/blob/master/debugbreak-gdb.py) to automate the above. See [HOW-TO-USE-DEBUGBREAK-GDB-PY.md](HOW-TO-USE-DEBUGBREAK-GDB-PY.md) for sample usage. ``` $ arm-none-linux-gnueabi-gdb -x debugbreak-gdb.py test/break-c++ <...> (gdb) run Program received signal SIGTRAP, Trace/breakpoint trap. main () at test/break-c++.cc:6 6 debug_break(); (gdb) debugbreak-step 7 std::cout << "hello, world\n"; ``` On AArch64, **debug_break()** generates **.inst 0xd4200000**. See table below for the behavior of **debug_break()** on other architecturs. Behavior on Different Architectures ---------------- | Architecture | debug_break() | | ------------- | ------------- | | x86/x86-64 | `int3` | | ARM mode, 32-bit | `.inst 0xe7f001f0` | | Thumb mode, 32-bit | `.inst 0xde01` | | AArch64, ARMv8 | `.inst 0xd4200000` | | POWER | `.4byte 0x7d821008` | | RISC-V | `.4byte 0x00100073` | | MSVC compiler | `__debugbreak` | | Apple compiler on AArch64 | `__builtin_trap()` | | Otherwise | `raise(SIGTRAP)` | debugbreak-1.0/debugbreak-gdb.py000066400000000000000000000136541400763333500166610ustar00rootroot00000000000000# Copyright (c) 2013, Scott Tsai # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # Usage: gdb -x debugbreak-gdb.py # (gdb) debugbreak-step # (gdb) debugbreak-continue # # To debug: # (gdb) set python print-stack full import gdb import re def _gdb_show_version_parse(version_str): ''' >>> s0 = 'This GDB was configured as "x86_64-redhat-linux-gnu".' >>> s1 = 'This GDB was configured as "--host=i686-build_pc-linux-gnu --target=arm-linux-gnueabihf".' >>> s2 = 'This GDB was configured as "x86_64-unknown-linux-gnu".' >>> _gdb_show_version_parse(s0) == dict(target='x86_64-redhat-linux-gnu') True >>> _gdb_show_version_parse(s1) == dict(host='i686-build_pc-linux-gnu', target='arm-linux-gnueabihf') True >>> _gdb_show_version_parse(s2) == dict(target='x86_64-unknown-linux-gnu') True ''' t = version_str msg = 'This GDB was configured as "' s = t.find(msg) if s == -1: raise ValueError s += len(msg) e = t.find('".', s) if e == -1: raise ValueError config = t[s:e] d = {} for i in config.split(): i = i.strip() if i.startswith('--'): (k, v) = i[2:].split('=') d[k] = v else: if not i: continue d['target'] = i return d def _target_triplet(): ''' -> 'arm-linux-gnueabihf' or 'x86_64-redhat-linux-gnu' or ... >>> import re >>> not not re.match(r'\w*-\w*-\w*', target_triplet()) True ''' t = gdb.execute('show version', to_string=True) return _gdb_show_version_parse(t)['target'] temp_breakpoint_num = None def on_stop_event(e): global temp_breakpoint_num if not isinstance(e, gdb.BreakpointEvent): return for bp in e.breakpoints: if bp.number == temp_breakpoint_num: bp.delete() gdb.events.stop.disconnect(on_stop_event) l = gdb.find_pc_line(int(gdb.parse_and_eval('$pc'))).line gdb.execute('list %d, %d' % (l, l)) break def _next_instn_jump_len(gdb_frame): '-> None means don\'t jump' try: arch_name = gdb_frame.architecture().name() except AttributeError: arch_name = None if arch_name.startswith('powerpc:'): # 'powerpc:common64' on ppc64 big endian i = bytes(gdb.selected_inferior().read_memory(gdb.parse_and_eval('$pc'), 4)) if (i == b'\x7d\x82\x10\x08') or (i == b'\x08\x10\x82\x7d'): return 4 else: # not stopped on a breakpoint instruction return None triplet = _target_triplet() if re.match(r'^arm-', triplet): i = bytes(gdb.selected_inferior().read_memory(gdb.parse_and_eval('$pc'), 4)) if i == b'\xf0\x01\xf0\xe7': return 4 elif i.startswith(b'\x01\xde'): return 2 elif i == b'\xf0\xf7\x00\xa0 ': # 'arm_linux_thumb2_le_breakpoint' from arm-linux-tdep.c in GDB return 4 else: # not stopped on a breakpoint instruction return None return None def _debugbreak_step(): global temp_breakpoint_num try: frame = gdb.selected_frame() except gdb.error as e: # 'No frame is currently selected.' gdb.write(e.args[0] + '\n', gdb.STDERR) return instn_len = _next_instn_jump_len(frame) if instn_len is None: gdb.execute('stepi') else: loc = '*($pc + %d)' % (instn_len,) bp = gdb.Breakpoint(loc, gdb.BP_BREAKPOINT, internal=True) bp.silent = True temp_breakpoint_num = bp.number gdb.events.stop.connect(on_stop_event) gdb.execute('jump ' + loc) def _debugbreak_continue(): try: frame = gdb.selected_frame() except gdb.error as e: # 'No frame is currently selected.' gdb.write(e.args[0] + '\n', gdb.STDERR) return instn_len = _next_instn_jump_len(frame) if instn_len is None: gdb.execute('continue') else: loc = '*($pc + %d)' % (instn_len,) gdb.execute('jump ' + loc) class _DebugBreakStep(gdb.Command): '''Usage: debugbreak-step Step one instruction after a debug_break() breakpoint hit''' def __init__(self): gdb.Command.__init__(self, 'debugbreak-step', gdb.COMMAND_BREAKPOINTS, gdb.COMPLETE_NONE) def invoke(self, arg, from_tty): _debugbreak_step() class _DebugBreakContinue(gdb.Command): '''Usage: debugbreak-continue Continue execution after a debug_break() breakpoint hit''' def __init__(self): gdb.Command.__init__(self, 'debugbreak-continue', gdb.COMMAND_BREAKPOINTS, gdb.COMPLETE_NONE) def invoke(self, arg, from_tty): _debugbreak_continue() _DebugBreakStep() _DebugBreakContinue() debugbreak-1.0/debugbreak.h000066400000000000000000000124401400763333500157160ustar00rootroot00000000000000/* Copyright (c) 2011-2021, Scott Tsai * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef DEBUG_BREAK_H #define DEBUG_BREAK_H #ifdef _MSC_VER #define debug_break __debugbreak #else #ifdef __cplusplus extern "C" { #endif #define DEBUG_BREAK_USE_TRAP_INSTRUCTION 1 #define DEBUG_BREAK_USE_BULTIN_TRAP 2 #define DEBUG_BREAK_USE_SIGTRAP 3 #if defined(__i386__) || defined(__x86_64__) #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION __inline__ static void trap_instruction(void) { __asm__ volatile("int $0x03"); } #elif defined(__thumb__) #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION /* FIXME: handle __THUMB_INTERWORK__ */ __attribute__((always_inline)) __inline__ static void trap_instruction(void) { /* See 'arm-linux-tdep.c' in GDB source. * Both instruction sequences below work. */ #if 1 /* 'eabi_linux_thumb_le_breakpoint' */ __asm__ volatile(".inst 0xde01"); #else /* 'eabi_linux_thumb2_le_breakpoint' */ __asm__ volatile(".inst.w 0xf7f0a000"); #endif /* Known problem: * After a breakpoint hit, can't 'stepi', 'step', or 'continue' in GDB. * 'step' would keep getting stuck on the same instruction. * * Workaround: use the new GDB commands 'debugbreak-step' and * 'debugbreak-continue' that become available * after you source the script from GDB: * * $ gdb -x debugbreak-gdb.py <... USUAL ARGUMENTS ...> * * 'debugbreak-step' would jump over the breakpoint instruction with * roughly equivalent of: * (gdb) set $instruction_len = 2 * (gdb) tbreak *($pc + $instruction_len) * (gdb) jump *($pc + $instruction_len) */ } #elif defined(__arm__) && !defined(__thumb__) #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION __attribute__((always_inline)) __inline__ static void trap_instruction(void) { /* See 'arm-linux-tdep.c' in GDB source, * 'eabi_linux_arm_le_breakpoint' */ __asm__ volatile(".inst 0xe7f001f0"); /* Known problem: * Same problem and workaround as Thumb mode */ } #elif defined(__aarch64__) && defined(__APPLE__) #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_BULTIN_TRAP #elif defined(__aarch64__) #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION __attribute__((always_inline)) __inline__ static void trap_instruction(void) { /* See 'aarch64-tdep.c' in GDB source, * 'aarch64_default_breakpoint' */ __asm__ volatile(".inst 0xd4200000"); } #elif defined(__powerpc__) /* PPC 32 or 64-bit, big or little endian */ #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION __attribute__((always_inline)) __inline__ static void trap_instruction(void) { /* See 'rs6000-tdep.c' in GDB source, * 'rs6000_breakpoint' */ __asm__ volatile(".4byte 0x7d821008"); /* Known problem: * After a breakpoint hit, can't 'stepi', 'step', or 'continue' in GDB. * 'step' stuck on the same instruction ("twge r2,r2"). * * The workaround is the same as ARM Thumb mode: use debugbreak-gdb.py * or manually jump over the instruction. */ } #elif defined(__riscv) /* RISC-V 32 or 64-bit, whether the "C" extension * for compressed, 16-bit instructions are supported or not */ #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION __attribute__((always_inline)) __inline__ static void trap_instruction(void) { /* See 'riscv-tdep.c' in GDB source, * 'riscv_sw_breakpoint_from_kind' */ __asm__ volatile(".4byte 0x00100073"); } #else #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_SIGTRAP #endif #ifndef DEBUG_BREAK_IMPL #error "debugbreak.h is not supported on this target" #elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_TRAP_INSTRUCTION __attribute__((always_inline)) __inline__ static void debug_break(void) { trap_instruction(); } #elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_BULTIN_TRAP __attribute__((always_inline)) __inline__ static void debug_break(void) { __builtin_trap(); } #elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_SIGTRAP #include __attribute__((always_inline)) __inline__ static void debug_break(void) { raise(SIGTRAP); } #else #error "invalid DEBUG_BREAK_IMPL value" #endif #ifdef __cplusplus } #endif #endif /* ifdef _MSC_VER */ #endif /* ifndef DEBUG_BREAK_H */ debugbreak-1.0/test/000077500000000000000000000000001400763333500144305ustar00rootroot00000000000000debugbreak-1.0/test/break-c++.cc000066400000000000000000000001671400763333500163750ustar00rootroot00000000000000#include #include "debugbreak.h" int main() { debug_break(); std::cout << "hello, world\n"; return 0; } debugbreak-1.0/test/break.c000066400000000000000000000001601400763333500156550ustar00rootroot00000000000000#include #include "debugbreak.h" int main() { debug_break(); printf("hello world\n"); return 0; } debugbreak-1.0/test/break.gdb000066400000000000000000000000171400763333500161700ustar00rootroot00000000000000file break run debugbreak-1.0/test/fib.c000066400000000000000000000003511400763333500153330ustar00rootroot00000000000000#include #include "debugbreak.h" int fib(int n) { int r; if (n == 0 || n == 1) return 1; r = fib(n-1) + fib(n-2); if (r == 89) { debug_break(); } return r; } int main() { printf("%d\n", fib(15)); return 0; } debugbreak-1.0/test/fib.gdb000066400000000000000000000000151400763333500156420ustar00rootroot00000000000000file fib run debugbreak-1.0/test/test-debugbreak.gdb000066400000000000000000000001421400763333500201530ustar00rootroot00000000000000source ../debugbreak-gdb.py file break-c++ # set remote exec-file break-c++ run #debugbreak-step debugbreak-1.0/test/trap.c000066400000000000000000000001331400763333500155370ustar00rootroot00000000000000#include int main() { __builtin_trap(); printf("hello world\n"); return 0; } debugbreak-1.0/test/trap.gdb000066400000000000000000000000501400763333500160470ustar00rootroot00000000000000file trap handle SIGILL stop nopass run