Changeset: fee1bc4eed90 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fee1bc4eed90
Modified Files:
        monetdb5/mal/mal.c
        monetdb5/mal/mal_debugger.c
        monetdb5/mal/mal_debugger.h
        monetdb5/mal/mal_interpreter.c
Branch: default
Log Message:

made the debugger optional, ie only when compiled with assert (ie with 
undefined NDEBUG)
the debugger is still available


diffs (truncated from 765 to 300 lines):

diff --git a/monetdb5/mal/mal.c b/monetdb5/mal/mal.c
--- a/monetdb5/mal/mal.c
+++ b/monetdb5/mal/mal.c
@@ -57,10 +57,12 @@ int mal_init(void){
  */
        if (!MCinit())
                return -1;
+#ifndef NDEBUG
        if (!mdbInit()) {
                mal_client_reset();
                return -1;
        }
+#endif
        monet_memory = MT_npages() * MT_pagesize();
        initNamespace();
        initParser();
@@ -71,7 +73,9 @@ int mal_init(void){
        str err = malBootstrap();
        if (err != MAL_SUCCEED) {
                mal_client_reset();
+#ifndef NDEBUG
                mdbExit();
+#endif
                dumpExceptionsToStream(NULL, err);
                freeException(err);
                return -1;
@@ -119,7 +123,9 @@ void mserver_reset(void)
        mal_module_reset();
        mal_atom_reset();
        opt_pipes_reset();
+#ifndef NDEBUG
        mdbExit();
+#endif
 
        memset((char*)monet_cwd, 0, sizeof(monet_cwd));
        monet_memory = 0;
diff --git a/monetdb5/mal/mal_debugger.c b/monetdb5/mal/mal_debugger.c
--- a/monetdb5/mal/mal_debugger.c
+++ b/monetdb5/mal/mal_debugger.c
@@ -44,19 +44,243 @@ typedef struct MDBSTATE{
 #define skipWord(c, X)     while (*(X) && (isalnum((unsigned char) *X))) { 
X++; } \
        skipBlanc(c, X);
 
-static void printStackElm(stream *f, MalBlkPtr mb, ValPtr v, int index, BUN 
cnt, BUN first);
-static void printStackHdr(stream *f, MalBlkPtr mb, ValPtr v, int index);
-static void printBATelm(stream *f, bat i, BUN cnt, BUN first);
-static void printBatDetails(stream *f, int bid);
-static void printBatInfo(stream *f, VarPtr n, ValPtr v);
-static void printBatProperties(stream *f, VarPtr n, ValPtr v, str props);
-static void mdbHelp(stream *f);
+/* Utilities
+ * Dumping a stack on a file is primarilly used for debugging.
+ * Printing the stack requires access to both the symbol table and
+ * the stackframes in most cases.
+ * Beware that a stack frame need not be initialized with null values.
+ * It has been zeroed upon creation.
+ *
+ * The routine  can also be used to inspect the symbol table of
+ * arbitrary functions.
+ */
+static void
+printStackHdr(stream *f, MalBlkPtr mb, ValPtr v, int index)
+{
+       VarPtr n = getVar(mb, index);
+
+       if (v == 0 && isVarConstant(mb, index))
+               v = &getVarConstant(mb, index);
+       mnstr_printf(f, "#[%2d] %5s", index, n->id);
+       mnstr_printf(f, " (%d,%d,%d) = ", getBeginScope(mb,index), 
getLastUpdate(mb,index),getEndScope(mb, index));
+       if (v)
+               ATOMprint(v->vtype, VALptr(v), f);
+}
+
+static void
+printBATproperties(stream *f, BAT *b)
+{
+       mnstr_printf(f, " count=" BUNFMT " lrefs=%d ",
+                       BATcount(b), BBP_lrefs(b->batCacheid));
+       if (BBP_refs(b->batCacheid) - 1)
+               mnstr_printf(f, " refs=%d ", BBP_refs(b->batCacheid));
+       if (b->batSharecnt)
+               mnstr_printf(f, " views=%d", b->batSharecnt);
+       if (b->theap.parentid)
+               mnstr_printf(f, "view on %s ", BBPname(b->theap.parentid));
+}
+
+static void
+printBATelm(stream *f, bat i, BUN cnt, BUN first)
+{
+       BAT *b, *bs[2]={0};
+       str tpe;
+
+       b = BATdescriptor(i);
+       if (b) {
+               tpe = getTypeName(newBatType(b->ttype));
+               mnstr_printf(f, ":%s ", tpe);
+               GDKfree(tpe);
+               printBATproperties(f, b);
+               /* perform property checking */
+               BATassertProps(b);
+               mnstr_printf(f, "\n");
+               if (cnt && BATcount(b) > 0) {
+                       if (cnt < BATcount(b)) {
+                               mnstr_printf(f, "Sample " BUNFMT " out of " 
BUNFMT "\n", cnt, BATcount(b));
+                       }
+                       /* cut out a portion of the BAT for display */
+                       bs[1] = BATslice(b, first, first + cnt);
+                       /* get the void values */
+                       if (bs[1] == NULL)
+                               mnstr_printf(f, "Failed to take chunk\n");
+                       else {
+                               bs[0] = BATdense(bs[1]->hseqbase, 0, 
BATcount(bs[1]));
+                               if( bs[0] == NULL){
+                                       mnstr_printf(f, "Failed to take chunk 
index\n");
+                               } else {
+                                       BATprintcolumns(f, 2, bs);
+                                       BBPunfix(bs[0]->batCacheid);
+                                       BBPunfix(bs[1]->batCacheid);
+                               }
+                       }
+               }
+
+               BBPunfix(b->batCacheid);
+       } else
+               mnstr_printf(f, "\n");
+}
+
+static void
+printStackElm(stream *f, MalBlkPtr mb, ValPtr v, int index, BUN cnt, BUN first)
+{
+       str nme, nmeOnStk;
+       VarPtr n = getVar(mb, index);
+
+       printStackHdr(f, mb, v, index);
+
+       if (v && v->vtype == TYPE_bat) {
+               bat i = v->val.bval;
+               BAT *b = BBPquickdesc(i, true);
+
+               if (b) {
+                       nme = getTypeName(newBatType(b->ttype));
+                       mnstr_printf(f, " :%s rows="BUNFMT, nme, BATcount(b));
+               } else {
+                       nme = getTypeName(n->type);
+                       mnstr_printf(f, " :%s", nme);
+               }
+       } else {
+               nme = getTypeName(n->type);
+               mnstr_printf(f, " :%s", nme);
+       }
+       nmeOnStk = v ? getTypeName(v->vtype) : GDKstrdup(nme);
+       /* check for type errors */
+       if (strcmp(nmeOnStk, nme) && strncmp(nmeOnStk, "BAT", 3))
+               mnstr_printf(f, "!%s ", nmeOnStk);
+       mnstr_printf(f, " %s", (isVarConstant(mb, index) ? " constant" : ""));
+       mnstr_printf(f, " %s", (isVarUsed(mb,index) ? "": " not used" ));
+       mnstr_printf(f, " %s", (isVarTypedef(mb, index) ? " type variable" : 
""));
+       GDKfree(nme);
+       mnstr_printf(f, "\n");
+       GDKfree(nmeOnStk);
+
+       if (cnt && v && (isaBatType(n->type) || v->vtype == TYPE_bat) && 
!is_bat_nil(v->val.bval)) {
+               printBATelm(f,v->val.bval,cnt,first);
+       }
+}
 
-static mdbStateRecord *mdbTable;
+void
+printStack(stream *f, MalBlkPtr mb, MalStkPtr s)
+{
+       int i = 0;
+
+       if (s) {
+               mnstr_printf(f, "#Stack '%s' size=%d top=%d\n",
+                               getInstrPtr(mb, 0)->fcnname, s->stksize, 
s->stktop);
+               for (; i < mb->vtop; i++)
+                       printStackElm(f, mb, s->stk + i, i, 0, 0);
+       } else
+               for (; i < mb->vtop; i++)
+                       printStackElm(f, mb, 0, i, 0, 0);
+}
+
+/* utility to display an instruction being called and its stack position */
+static void
+printCall(Client cntxt, MalBlkPtr mb, MalStkPtr stk, int pc)
+{
+       str msg;
+       msg = instruction2str(mb, stk, getInstrPtr(mb, pc), LIST_MAL_CALL);
+       mnstr_printf(cntxt->fdout, "#%s at %s.%s[%d]\n", (msg?msg:"failed 
instruction2str()") ,
+                       getModuleId(getInstrPtr(mb, 0)),
+                       getFunctionId(getInstrPtr(mb, 0)), pc);
+       GDKfree(msg);
+}
+
+static void
+mdbBacktrace(Client cntxt, MalStkPtr stk, int pci)
+{
+       for (; stk != NULL; stk = stk->up) {
+               printCall(cntxt, stk->blk, stk, pci);
+               if (stk->up)
+                       pci = stk->up->pcup;
+       }
+}
+
+void
+mdbDump(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       int i = getPC(mb, pci);
+       mnstr_printf(cntxt->fdout, "!MDB dump of instruction %d\n", i);
+       if( i < 0)
+               return;
+       printFunction(cntxt->fdout, mb, stk, LIST_MAL_ALL);
+       mdbBacktrace(cntxt, stk, i);
+       printStack(cntxt->fdout, mb, stk);
+}
+
+#ifndef NDEBUG
+static void
+printBatDetails(stream *f, bat bid)
+{
+       BAT *b[2];
+       bat ret,ret2;
+       MALfcn fcn;
+
+       /* at this level we don't know bat kernel primitives */
+       mnstr_printf(f, "#Show info for %d\n", bid);
+       fcn = getAddress("BKCinfo");
+       if (fcn) {
+               (*fcn)(&ret,&ret2, &bid);
+               b[0] = BATdescriptor(ret);
+               if (b[0] == NULL)
+                       return;
+               b[1] = BATdescriptor(ret2);
+               if (b[1] == NULL) {
+                       BBPunfix(b[0]->batCacheid);
+                       return;
+               }
+               BATprintcolumns(f, 2, b);
+               BBPunfix(b[0]->batCacheid);
+               BBPunfix(b[1]->batCacheid);
+       }
+}
+
+static void
+printBatInfo(stream *f, VarPtr n, ValPtr v)
+{
+       if (isaBatType(n->type) && v->val.ival)
+               printBatDetails(f, v->val.ival);
+}
+
+static void
+mdbHelp(stream *f)
+{
+       mnstr_printf(f, "next             -- Advance to next statement\n");
+       mnstr_printf(f, "continue         -- Continue program being 
debugged\n");
+       mnstr_printf(f, "catch            -- Catch the next exception \n");
+       mnstr_printf(f, "break [<var>]    -- set breakpoint on current 
instruction or <var>\n");
+       mnstr_printf(f, "delete [<var>]   -- remove break/trace point <var>\n");
+       mnstr_printf(f, "debug <int>      -- set kernel debugging mask\n");
+       mnstr_printf(f, "step             -- advance to next MAL 
instruction\n");
+       mnstr_printf(f, "module           -- display a module signatures\n");
+       mnstr_printf(f, "atom             -- show atom list\n");
+       mnstr_printf(f, "finish           -- finish current call\n");
+       mnstr_printf(f, "exit             -- terminate executionr\n");
+       mnstr_printf(f, "quit             -- turn off debugging\n");
+       mnstr_printf(f, "list <obj>       -- list current program block\n");
+       mnstr_printf(f, "list #  [+#],-#  -- list current program block 
slice\n");
+       mnstr_printf(f, "List <obj> [#]   -- list with type 
information[slice]\n");
+       mnstr_printf(f, "list [#] <obj>   -- list program block after optimizer 
<#>\n");
+       mnstr_printf(f, "List #  [+#],-#  -- list current program block 
slice\n");
+       mnstr_printf(f, "var  <obj>       -- print symbol table for module\n");
+       mnstr_printf(f, "optimizer <obj>  -- display optimizer steps\n");
+       mnstr_printf(f, "print <var>      -- display value of a variable\n");
+       mnstr_printf(f, "print <var> <cnt>[<first>] -- display BAT chunk\n");
+       mnstr_printf(f, "info <var>       -- display bat variable 
properties\n");
+       mnstr_printf(f, "run              -- restart current procedure\n");
+       mnstr_printf(f, "where            -- print stack trace\n");
+       mnstr_printf(f, "down             -- go down the stack\n");
+       mnstr_printf(f, "up               -- go up the stack\n");
+       mnstr_printf(f, "trace <var>      -- trace assignment to variables\n");
+       mnstr_printf(f, "trap <mod>.<fcn> -- catch MAL function call in 
debugger\n");
+       mnstr_printf(f, "help             -- this message\n");
+}
 
 /*
  * The debugger flags overview
  */
+static mdbStateRecord *mdbTable;
 
 bool
 mdbInit(void)
@@ -258,18 +482,6 @@ mdbClrBreakRequest(Client cntxt, str req
        mdb->brkTop = j;
 }
 
-/* utility to display an instruction being called and its stack position */
-static void
-printCall(Client cntxt, MalBlkPtr mb, MalStkPtr stk, int pc)
-{
-       str msg;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to