a bunch of stuff, i don't know master
authorkremlin <ian@kremlin.cc>
Sat, 10 Jun 2017 06:43:14 +0000 (01:43 -0500)
committerkremlin <ian@kremlin.cc>
Sat, 10 Jun 2017 06:43:14 +0000 (01:43 -0500)
Makefile
README [new file with mode: 0644]
puffcrash.1 [new file with mode: 0644]
puffcrash.c
puffcrash.conf [new file with mode: 0644]

index 1ea72ce1ee88d1d670972922a69451d3de21a57a..c5c3498669184a2e8278c89afed9d1f188ceff57 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,3 +20,5 @@ build:
 
 install: build
        install -c -s -o root -g bin -m 555 $(OUT) $(DESTDIR)$(OUT)
+       install -c -o root -g wheel -m 664 puffcrash.conf /etc/puffcrash.conf
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9241560
--- /dev/null
+++ b/README
@@ -0,0 +1,7 @@
+puffcrash reads serial terminal output from openbsd machines & listens for
+kernel panics. when detected & following 'trace' command is issued to ddb(4),
+puffcrash tries to ascertain the source lines implicated in the crash via
+objdump(1)
+
+options:
+
diff --git a/puffcrash.1 b/puffcrash.1
new file mode 100644 (file)
index 0000000..b8ccc9b
--- /dev/null
@@ -0,0 +1,48 @@
+.\" Copyright (c) 2017 Ian Sutton <ian@ce.gl>$
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: June 10 2017 $
+.Dt PUFFCRASH 1
+.Os
+.Sh NAME
+.Nm puffcrash
+.Nd OpenBSD kernel debugging assitant
+.Sh SYNOPSIS
+.Nm
+.Op Fl c Ar config
+.Op Ar serial\ console\ log
+.Sh DESCRIPTION
+.Nm
+reads serial terminal output from OpenBSD machines, listening for
+kernel panics.
+When detected (and following 'trace' command is issued to
+.Xr ddb 4 ,
+puffcrash tries to ascertain the source lines implicated in the crash via
+.Xr objdump 1
+and source tags (usually generated by `make tags`), displaying them if succesful.
+.Pp
+.Nm
+reads from standard input if logfile argument is omitted.
+.Sh SEE ALSO
+.Xr ddb 4
+.Sh HISTORY
+.Nm
+does not appear in
+.Ox 6.1
+currently.
+.Sh AUTHORS
+.An -nosplit
+.Nm
+was written by
+.An Ian Sutton Aq Mt ian@ce.gl .
index 3419f8ab98151f099f7706f13597a6ddff242e90..b043db7fd7887d0ce3cbc43908f95beebc34028c 100644 (file)
  */
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <signal.h>
+
+#define LINE_SIZE 4096
+
+struct config {
+       char *obj_path;
+       char *tool_path;
+       char *src_path;
+       FILE *conf;
+       FILE *term;
+} *gcfg;
+
+struct sigaction sigact;
+static void sigh(int);
+static void sigc(void);
+
+static void __dead
+usage(void)
+{
+       fprintf(stderr, "usage: puffcrash [-c config] [serial console log]\n");
+       exit(1);
+}
+
+void
+sigh(int sig)
+{
+       if (sig == SIGINT) sigc();
+}
+
+void
+sigc(void)
+{
+       if (gcfg->obj_path) free(gcfg->obj_path);
+       if (gcfg->tool_path) free(gcfg->tool_path);
+       if (gcfg->src_path) free(gcfg->src_path);
+
+       if (gcfg->conf) fclose(gcfg->conf);
+       if (gcfg->term && gcfg->term != stdin) fclose(gcfg->term);
+
+       exit(1);
+}
+
+int
+parse_config(char *config_path, struct config *cfg)
+{
+       char *line, *i;
+       int check = 0;
+
+       cfg->conf = fopen(config_path, "r");
+
+       if(!(line = calloc(1, 256)) || !cfg->conf)
+           return 1;
+
+       while ((fgets(line, 256, cfg->conf))) {
+           if (strstr(line, "obj_path")) {
+               i = strstr(line, "=") + 2;
+               strlcpy(cfg->obj_path, i, PATH_MAX);
+               check |= (1 << 0);
+           } else if (strstr(line, "tool_path")) {
+               i = strstr(line, "=") + 2;
+               strlcpy(cfg->tool_path, i, PATH_MAX);
+               check |= (1 << 1);
+           } else if (strstr(line, "src_path")) {
+               i = strstr(line, "=") + 2;
+               strlcpy(cfg->src_path, i, PATH_MAX);
+               check |= (1 << 2);
+           }
+       }
+
+       free(line);
+
+       if (check == 0x7)
+           return 0;
+       else
+           return 1;
+}
+
+void
+watch_serial(void)
+{
+       char *line;
+
+       if (!(line = calloc(1, LINE_SIZE))) {
+           printf("could not allocate memory\n");
+           sigc();
+       }
+
+       while ((fgets(line, LINE_SIZE, gcfg->term))) {
+           printf("%s", line);
+       }
+}
 
 int
 main(int argc, char *argv[])
 {
+       struct config cfg;
+       int ch;
+       char term_path[PATH_MAX], config_path[PATH_MAX];
+
+       bzero(&cfg, sizeof(struct config));
+       strlcpy(config_path, "/etc/puffcrash.conf", PATH_MAX);
+
+       atexit(sigc);
+       sigact.sa_handler = sigh;
+       sigemptyset(&sigact.sa_mask);
+       sigact.sa_flags = 0;
+       sigaction(SIGINT, &sigact, (struct sigaction *) NULL);
+
+       while ((ch = getopt(argc, argv, "c:")) != -1) {
+           switch (ch) {
+           case 'c':
+               strlcpy(config_path, optarg, PATH_MAX);
+               break;
+           default:
+               usage();
+               break;
+           }
+       }
+
+       argv += optind;
+       argc -= optind;
+
+       cfg.obj_path  = calloc(1, PATH_MAX);
+       cfg.tool_path = calloc(1, PATH_MAX);
+       cfg.src_path  = calloc(1, PATH_MAX);
+
+       gcfg = &cfg;
+
+       if (parse_config(config_path, &cfg)) {
+           printf("failed to parse config file %s.\n", config_path);
+           sigc();
+       }
+
+       if (argc) {
+           strlcpy(term_path, argv[0], PATH_MAX);
+           cfg.term = fopen(term_path, "r");
+       } else
+           cfg.term = stdin;
+
+       if (!cfg.term) {
+           printf("failed to open serial console output logfile \"%s\"\n", argv[0]);
+           sigc();
+       }
+
+       watch_serial();
+
        return 0;
 }
diff --git a/puffcrash.conf b/puffcrash.conf
new file mode 100644 (file)
index 0000000..31deed9
--- /dev/null
@@ -0,0 +1,3 @@
+obj_path  = /usr/src/sys/arch/armv7/compile/MMCDMA/obj.amd64.armv7/
+tool_path = /usr/cross/armv7/usr/bin/
+src_path  = /usr/src/sys/arch/armv7/