add advanced hang analyzer.
authormickey <mickey@openbsd.org>
Sun, 5 May 1996 12:23:06 +0000 (12:23 +0000)
committermickey <mickey@openbsd.org>
Sun, 5 May 1996 12:23:06 +0000 (12:23 +0000)
idea by theo.

sys/conf/files
sys/ddb/db_aout.c
sys/ddb/db_command.c
sys/ddb/db_extern.h
sys/ddb/db_hangman.c [new file with mode: 0644]
sys/ddb/db_input.c
sys/ddb/db_sym.c
sys/ddb/db_sym.h

index 94c91c2..496f4ef 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: files,v 1.17 1996/05/02 13:46:29 deraadt Exp $
+#      $OpenBSD: files,v 1.18 1996/05/05 12:23:24 mickey Exp $
 #      $NetBSD: files,v 1.83 1996/04/25 02:18:25 thorpej Exp $
 
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
@@ -82,6 +82,7 @@ file ddb/db_variables.c                       ddb
 file ddb/db_watch.c                    ddb
 file ddb/db_write_cmd.c                        ddb
 file ddb/db_usrreq.c                   ddb
+file ddb/db_hangman.c                  ddb
 file dev/audio.c                       audio                   needs-flag
 file dev/ccd.c                         ccd                     needs-flag
 file dev/ic/aic7xxx.c                  aic7xxx
index 3085806..667f62f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_aout.c,v 1.6 1996/04/19 16:08:28 niklas Exp $      */
+/*     $OpenBSD: db_aout.c,v 1.7 1996/05/05 12:23:06 mickey Exp $      */
 /*     $NetBSD: db_aout.c,v 1.14 1996/02/27 20:54:43 gwr Exp $ */
 
 /* 
@@ -137,6 +137,24 @@ X_db_sym_init(symtab, esymtab, name)
         }
 }
 
+size_t
+X_db_nsyms(stab)
+       db_symtab_t     *stab;
+{
+       return (struct nlist *)stab->end - (struct nlist *)stab->start;
+}
+
+db_sym_t
+X_db_isym(stab, i)
+       db_symtab_t     *stab;
+       size_t          i;
+{
+       if (i >= X_db_nsyms(stab))
+               return NULL;
+       else
+               return (db_sym_t)((struct nlist *)stab->start + i);
+}
+
 db_sym_t
 X_db_lookup(stab, symstr)
        db_symtab_t     *stab;
@@ -220,7 +238,8 @@ X_db_symbol_values(sym, namep, valuep)
 {
        register struct nlist *sp;
 
-       sp = (struct nlist *)sym;
+       if ((sp = (struct nlist *)sym) == NULL)
+           return;
        if (namep)
            *namep = sp->n_un.n_name;
        if (valuep)
index 6867eba..5f1970b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_command.c,v 1.7 1996/04/21 22:18:57 deraadt Exp $  */
+/*     $OpenBSD: db_command.c,v 1.8 1996/05/05 12:23:09 mickey Exp $   */
 /*     $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */
 
 /* 
@@ -380,6 +380,7 @@ struct db_command db_command_table[] = {
        { "callout",    db_show_callout,        0,              NULL },
        { "show",       NULL,                   0,              db_show_cmds },
        { "boot",       NULL,                   0,              db_boot_cmds },
+       { "hangman",    db_hangman,             0,              NULL },
        { NULL,         NULL,                   0,              NULL }
 };
 
index 9c19f79..60a01b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_extern.h,v 1.2 1996/03/11 11:16:07 mickey Exp $    */
+/*     $OpenBSD: db_extern.h,v 1.3 1996/05/05 12:23:11 mickey Exp $    */
 /*     $NetBSD: db_extern.h,v 1.1 1996/02/05 01:57:00 christos Exp $   */
 
 /*
@@ -34,6 +34,8 @@
 
 /* db_aout.c */
 void X_db_sym_init __P((int *, char *, char *));
+size_t X_db_nsyms __P((db_symtab_t *));
+db_sym_t X_db_isym __P((db_symtab_t *, size_t));
 db_sym_t X_db_lookup __P((db_symtab_t *, char *));
 db_sym_t X_db_search_symbol __P((db_symtab_t *, db_addr_t, db_strategy_t,
                                 db_expr_t *));
diff --git a/sys/ddb/db_hangman.c b/sys/ddb/db_hangman.c
new file mode 100644 (file)
index 0000000..f4b2d4d
--- /dev/null
@@ -0,0 +1,194 @@
+/*     $OpenBSD: db_hangman.c,v 1.1 1996/05/05 12:23:14 mickey Exp $   */
+
+/*
+ * Copyright (c) 1996 Theo de Raadt, Michael Shalayeff
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the authors may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 REGENTS 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.
+ *
+ */
+
+#include <sys/param.h>
+#include <machine/db_machdep.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_extern.h>
+#include <dev/cons.h>
+#include "rnd.h"
+#if NRND
+#include <dev/rndvar.h>
+#endif
+
+#define        TOLOWER(c)      (('A'<=(c)&&(c)<='Z')?(c)-'a'+'A':(c))
+#define        ISALPHA(c)      (('a'<=(c)&&(c)<='z')||('A'<=(c)&&(c)<='Z'))
+
+static __inline size_t
+db_random( mod )
+       register size_t mod;
+{
+#if NRND
+       size_t  ret;
+       get_random_bytes(&ret, sizeof(ret) );
+       return ret % mod;
+#else
+       u_int random();
+       return (size_t)(random() % mod);
+#endif
+}
+
+static int     skill;
+
+static __inline char *
+db_randomsym(lenp)
+       size_t  *lenp;
+{
+       register char   *p, *q;
+               /* choose random symtab */
+       register db_symtab_t    *stab = db_istab(db_random(db_nsymtabs));
+
+               /* choose random symbol from the table */
+       q = db_qualify(X_db_isym(stab, db_random(X_db_nsyms(stab))),stab->name);
+
+               /* strlen(q) && ignoring underscores and colons */
+       for ((*lenp) = 0, p = q; *p; p++)
+               if (ISALPHA(*p))
+                       (*lenp)++;
+
+       return q;
+}
+
+
+static int
+db_hang(tries, word, abc)
+       int     tries;
+       register char   *word;
+       register char   *abc;
+{
+       register char   *p;
+       register int    n = 6;
+
+       cnputc(' ');
+       for (p = word; *p; p++, n++)
+               if (ISALPHA(*p))
+                       cnputc(abc[TOLOWER(*p) - 'a']);
+               else
+                       cnputc(*p);
+
+       cnputc(' ');
+       cnputc('(');
+       cnputc('0' + tries);
+       cnputc(' ');
+
+       for (p = abc; *p; p++)
+               if (*p == '_') {
+                       cnputc('a' + (p - abc));
+                       n++;
+               }
+
+       cnputc(')');
+
+               /* position to the beginning of the line */
+       while (n--)
+               cnputc('\b');
+}
+
+
+static int
+db_hangon(void)
+{
+       static size_t   len;
+       static size_t   tries;
+       static char     *word = NULL;
+       static char     abc[26+1];      /* for '\0' */
+
+       if (word == NULL) {
+               register char   *p;
+
+               for (p = abc; p < &abc[sizeof(abc)-1]; p++)
+                       *p = '-';
+               *p = '\0';
+
+               tries = 2 * (1 + skill / 3);
+               word = db_randomsym(&len);
+       }
+
+       {
+               register char   c, c1;
+
+               db_hang(tries, word, abc);
+               c1 = cngetc();
+
+               c = TOLOWER(c1);
+               if (ISALPHA(c) && abc[c - 'a'] == '-') {
+                       register char   *p;
+                       register size_t n;
+
+                               /* strchr(word,c) */
+                       for (n = 0, p = word; *p ; p++)
+                               if (*p == c)
+                                       n++;
+
+                       if (n) {
+                               abc[c - 'a'] = c1;
+                               len -= n;
+                       } else {
+                               abc[c - 'a'] = '_';
+                               tries--;
+                       }
+               }
+       }
+
+       if (tries && len)
+               return db_hangon();
+
+       if (!tries && skill > 2)
+       {
+               register char   *p = word;
+               for (; *p; p++)
+                       if (ISALPHA(*p))
+                               abc[TOLOWER(*p) - 'a'] = *p;
+       }
+       db_hang(tries, word, abc);
+       cnputc('\n');
+       word = NULL;
+
+       return !tries;
+}
+
+void
+db_hangman( addr, haddr, count, modif)
+       db_expr_t addr;
+       int     haddr;
+       db_expr_t count;
+       char    *modif;
+{
+       if (modif[0] == 's' && '0' <= modif[1] && modif[1] <= '9')
+               skill = modif[1] - '0';
+       else
+               skill = 0;
+
+       while (db_hangon());
+}
index c2638e4..56d7a4f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_input.c,v 1.4 1996/04/21 22:19:01 deraadt Exp $    */
+/*     $OpenBSD: db_input.c,v 1.5 1996/05/05 12:23:16 mickey Exp $     */
 /*     $NetBSD: db_input.c,v 1.7 1996/02/05 01:57:02 christos Exp $    */
 
 /* 
@@ -174,6 +174,11 @@ db_inputchar(c)
                    db_lc++;
                }
                break;
+           case CTRL('w'):
+               /* erase word back */
+               while (db_lc > db_lbuf_start && *db_lc != BLANK)
+                   db_delete(1, DEL_BWD);
+               break;
            case CTRL('h'):
            case 0177:
                /* erase previous character */
index f0b2c71..bb99d31 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_sym.c,v 1.7 1996/04/21 22:19:13 deraadt Exp $      */
+/*     $OpenBSD: db_sym.c,v 1.8 1996/05/05 12:23:18 mickey Exp $       */
 /*     $NetBSD: db_sym.c,v 1.12 1996/02/05 01:57:15 christos Exp $     */
 
 /* 
 #endif
 
 db_symtab_t    db_symtabs[MAXNOSYMTABS] = {{0,},};
+size_t         db_nsymtabs = 0;
 
 db_symtab_t    *db_last_symtab;
 
-static char *db_qualify __P((db_sym_t, char *));
-
 /*
  * Add symbol table, with given name, to list of symbol tables.
  */
@@ -79,6 +78,7 @@ db_add_symbol_table(start, end, name, ref)
        db_symtabs[slot].end = end;
        db_symtabs[slot].name = name;
        db_symtabs[slot].private = ref;
+       db_nsymtabs++;
 
        return(slot);
 }
@@ -102,19 +102,32 @@ db_del_symbol_table(name)
                return;
        }
 
+       db_nsymtabs--;
        db_symtabs[slot].start = 0;
        db_symtabs[slot].end = 0;
        db_symtabs[slot].name = 0;
        db_symtabs[slot].private = 0;
 }
 
+db_symtab_t *
+db_istab(i)
+       size_t  i;
+{
+       register db_symtab_t    *stab;
+
+       for (stab = db_symtabs; i ; stab++)
+               if (stab->name != NULL)
+                       i--;
+       return stab;
+}
+
 /*
  *  db_qualify("vm_map", "bsd") returns "bsd:vm_map".
  *
  *  Note: return value points to static data whose content is
  *  overwritten by each call... but in practice this seems okay.
  */
-static char *
+char *
 db_qualify(sym, symtabname)
        db_sym_t        sym;
        register char   *symtabname;
index 9d2fe2c..b76aeb3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_sym.h,v 1.4 1996/04/21 22:19:15 deraadt Exp $      */
+/*     $OpenBSD: db_sym.h,v 1.5 1996/05/05 12:23:19 mickey Exp $       */
 /*     $NetBSD: db_sym.h,v 1.7 1996/02/05 01:57:16 christos Exp $      */
 
 /* 
@@ -41,6 +41,7 @@ typedef struct {
 } db_symtab_t;
 
 extern db_symtab_t     *db_last_symtab; /* where last symbol was found */
+extern size_t          db_nsymtabs;    /* number of symbol tables */
 
 /*
  * Symbol representation is specific to the symtab style:
@@ -75,6 +76,7 @@ int db_add_symbol_table __P((char *, char *, char *, char *));
 
 void db_del_symbol_table __P((char *));
                                        /* remove a symbol table from list */
+db_symtab_t *db_istab __P((size_t));
 
 boolean_t db_eqname __P((char *, char *, int));
                                        /* strcmp, modulo leading char */
@@ -84,6 +86,8 @@ int db_value_of_name __P((char *, db_expr_t *));
 
 db_sym_t db_lookup __P((char *));
 
+char *db_qualify __P((db_sym_t, char *));
+
 boolean_t db_symbol_is_ambiguous __P((db_sym_t));
 
 db_sym_t db_search_symbol __P((db_addr_t, db_strategy_t, db_expr_t *));
@@ -106,3 +110,6 @@ void db_printsym __P((db_expr_t, db_strategy_t));
 boolean_t db_line_at_pc __P((db_sym_t, char **, int *, db_expr_t));
 
 int db_sym_numargs __P((db_sym_t, int *, char **));
+
+/* db_hangman.c */
+void db_hangman __P((db_expr_t, int, db_expr_t, char *));