Browse Source

breakpoint: new module.

Thanks to Jeremy Kerr for the idea!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 13 years ago
parent
commit
9552c972f7

+ 1 - 0
Makefile-ccan

@@ -34,6 +34,7 @@ MODS_WITH_SRC := antithread \
 	avl \
 	avl \
 	bdelta \
 	bdelta \
 	block_pool \
 	block_pool \
+	breakpoint \
 	btree \
 	btree \
 	ccan_tokenizer \
 	ccan_tokenizer \
 	charset \
 	charset \

+ 1 - 0
ccan/breakpoint/LICENSE

@@ -0,0 +1 @@
+../../licenses/CC0

+ 33 - 0
ccan/breakpoint/_info

@@ -0,0 +1,33 @@
+#include <string.h>
+#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 <ccan/breakpoint/breakpoint.h>
+ *
+ *	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;
+}

+ 32 - 0
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 <ccan/breakpoint/breakpoint.h>
+
+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;
+	}
+}

+ 24 - 0
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 <ccan/compiler/compiler.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdbool.h>
+
+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 */

+ 17 - 0
ccan/breakpoint/test/run.c

@@ -0,0 +1,17 @@
+#include <ccan/breakpoint/breakpoint.h>
+#include <ccan/breakpoint/breakpoint.c>
+#include <ccan/tap/tap.h>
+
+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();
+}