From 9552c972f725f70ab024e0c9d0487ff078322fd8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 27 May 2013 21:53:55 +0930 Subject: [PATCH] breakpoint: new module. Thanks to Jeremy Kerr for the idea! Signed-off-by: Rusty Russell --- Makefile-ccan | 1 + ccan/breakpoint/LICENSE | 1 + ccan/breakpoint/_info | 33 +++++++++++++++++++++++++++++++++ ccan/breakpoint/breakpoint.c | 32 ++++++++++++++++++++++++++++++++ ccan/breakpoint/breakpoint.h | 24 ++++++++++++++++++++++++ ccan/breakpoint/test/run.c | 17 +++++++++++++++++ 6 files changed, 108 insertions(+) create mode 120000 ccan/breakpoint/LICENSE create mode 100644 ccan/breakpoint/_info create mode 100644 ccan/breakpoint/breakpoint.c create mode 100644 ccan/breakpoint/breakpoint.h create mode 100644 ccan/breakpoint/test/run.c diff --git a/Makefile-ccan b/Makefile-ccan index 7ae3863a..2d713a68 100644 --- a/Makefile-ccan +++ b/Makefile-ccan @@ -34,6 +34,7 @@ MODS_WITH_SRC := antithread \ avl \ bdelta \ block_pool \ + breakpoint \ btree \ ccan_tokenizer \ charset \ diff --git a/ccan/breakpoint/LICENSE b/ccan/breakpoint/LICENSE new file mode 120000 index 00000000..b7951dab --- /dev/null +++ b/ccan/breakpoint/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/ccan/breakpoint/_info b/ccan/breakpoint/_info new file mode 100644 index 00000000..5f5251e6 --- /dev/null +++ b/ccan/breakpoint/_info @@ -0,0 +1,33 @@ +#include +#include "config.h" + +/** + * breakpoint - break if the program is run under gdb. + * + * This code allows you to insert breakpoints within a program. These will + * do nothing unless your program is run under GDB. + * + * License: CC0 (Public domain) + * + * Example: + * #include + * + * int main(void) + * { + * breakpoint(); + * return 0; + * } + */ +int main(int argc, char *argv[]) +{ + /* Expect exactly one argument */ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + printf("ccan/compiler\n"); + return 0; + } + + return 1; +} diff --git a/ccan/breakpoint/breakpoint.c b/ccan/breakpoint/breakpoint.c new file mode 100644 index 00000000..279e29a1 --- /dev/null +++ b/ccan/breakpoint/breakpoint.c @@ -0,0 +1,32 @@ +/* CC0 (Public domain) - see LICENSE file for details + * + * Idea for implementation thanks to stackoverflow.com: + * http://stackoverflow.com/questions/3596781/detect-if-gdb-is-running + */ +#include + +bool breakpoint_initialized; +bool breakpoint_under_debug; + +/* This doesn't get called if we're under GDB. */ +static void trap(int signum) +{ + breakpoint_initialized = true; +} + +void breakpoint_init(void) +{ + struct sigaction old, new; + + new.sa_handler = trap; + new.sa_flags = 0; + sigemptyset(&new.sa_mask); + sigaction(SIGTRAP, &new, &old); + kill(getpid(), SIGTRAP); + sigaction(SIGTRAP, &old, NULL); + + if (!breakpoint_initialized) { + breakpoint_initialized = true; + breakpoint_under_debug = true; + } +} diff --git a/ccan/breakpoint/breakpoint.h b/ccan/breakpoint/breakpoint.h new file mode 100644 index 00000000..6283a010 --- /dev/null +++ b/ccan/breakpoint/breakpoint.h @@ -0,0 +1,24 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_BREAKPOINT_H +#define CCAN_BREAKPOINT_H +#include +#include +#include +#include +#include + +void breakpoint_init(void) COLD; +extern bool breakpoint_initialized; +extern bool breakpoint_under_debug; + +/** + * breakpoint - stop if running under the debugger. + */ +static inline void breakpoint(void) +{ + if (!breakpoint_initialized) + breakpoint_init(); + if (breakpoint_under_debug) + kill(getpid(), SIGTRAP); +} +#endif /* CCAN_BREAKPOINT_H */ diff --git a/ccan/breakpoint/test/run.c b/ccan/breakpoint/test/run.c new file mode 100644 index 00000000..b36e9c22 --- /dev/null +++ b/ccan/breakpoint/test/run.c @@ -0,0 +1,17 @@ +#include +#include +#include + +int main(void) +{ + /* This is how many tests you plan to run */ + plan_tests(2); + + breakpoint(); + + ok1(breakpoint_initialized); + ok1(!breakpoint_under_debug); + + /* This exits depending on whether all tests passed */ + return exit_status(); +} -- 2.39.2