Changeset: 5b4baab216cc for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5b4baab216cc
Added Files:
        monetdb5/mal/mal_debugger.c
        monetdb5/mal/mal_debugger.h
Removed Files:
        monetdb5/mal/mal_debugger.mx
Modified Files:
        monetdb5/mal/Makefile.ag
Branch: default
Log Message:

de-Mx mal_debugger.mx


diffs (truncated from 3554 to 300 lines):

diff --git a/monetdb5/mal/Makefile.ag b/monetdb5/mal/Makefile.ag
--- a/monetdb5/mal/Makefile.ag
+++ b/monetdb5/mal/Makefile.ag
@@ -32,7 +32,7 @@ lib_mal = {
                mal_box.c mal_box.h \
                mal_builder.c mal_builder.h \
                mal_client.c mal_client.h \
-               mal_debugger.mx \
+               mal_debugger.c mal_debugger.h \
                mal_errors.h \
                mal_exception.c mal_exception.h \
                mal_factory.c mal_factory.h \
diff --git a/monetdb5/mal/mal_debugger.c b/monetdb5/mal/mal_debugger.c
new file mode 100644
--- /dev/null
+++ b/monetdb5/mal/mal_debugger.c
@@ -0,0 +1,1690 @@
+/*
+ * The contents of this file are subject to the MonetDB Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.monetdb.org/Legal/MonetDBLicense
+ * 
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * The Original Code is the MonetDB Database System.
+ * 
+ * The Initial Developer of the Original Code is CWI.
+ * Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
+ * Copyright August 2008-2012 MonetDB B.V.
+ * All Rights Reserved.
+*/
+
+/*
+ * M.L. Kersten
+ * For documentation see website.
+ */
+#include "monetdb_config.h"
+#include "mal_readline.h"
+#include "mal_debugger.h"
+#include "mal_atom.h"          /* for showAtoms() */
+#include "mal_interpreter.h"   /* for getArgReference() */
+#include "mal_linker.h"                /* for getAddress() */
+#include "mal_listing.h"
+#include "mal_module.h"                /* for showModuleStatistics() */
+#include "mal_parser.h"
+#include "mal_namespace.h"
+
+#ifdef HAVE_SBRK
+#include <unistd.h>
+#endif
+
+int MDBdelay;                  /* do not immediately react */
+
+#define skipBlanc(c,X)    while(*(X) && isspace((int)*X)){ X++; }
+#define skipNonBlanc(c,X) while(*(X) && !isspace((int) *X)){ X++; }
+#define skipWord(c,X)    while(*(X) && isalnum((int) *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 mdbStateRecord *mdbTable;
+
+void
+mdbInit(void)
+{
+       /*
+        * Each client has its own breakpoint administration, kept in a
+        * global table.  Although a little space consumptive, it is the
+        * easiest to maintain and much less expensive as reserving debugger
+        * space in each instruction.
+        */
+       mdbTable = GDKzalloc(sizeof(mdbStateRecord) * MAL_MAXCLIENTS);
+}
+
+static char
+isBreakpoint(Client cntxt, MalBlkPtr mb, InstrPtr p, int pc)
+{
+       int i, j;
+
+       for (i = 0; i < mdbTable[cntxt->idx].brkTop; i++) {
+               if( mdbTable[cntxt->idx].brkBlock[i] != mb) 
+                       continue;
+               if( mdbTable[cntxt->idx].brkPc[i] == pc )
+                       return mdbTable[cntxt->idx].brkCmd[i];
+
+               if( mdbTable[cntxt->idx].brkMod[i] && getModuleId(p) &&
+                   mdbTable[cntxt->idx].brkFcn[i] && getFunctionId(p) &&
+                       strcmp(mdbTable[cntxt->idx].brkMod[i], 
getModuleId(p))==0 &&
+                       strcmp(mdbTable[cntxt->idx].brkFcn[i], 
getFunctionId(p))==0)
+                       return mdbTable[cntxt->idx].brkCmd[i];
+
+               if( mdbTable[cntxt->idx].brkVar[i] >= 0 )
+               for (j = 0; j < p->retc; j++)
+                       if (mdbTable[cntxt->idx].brkVar[i] == getArg(p,j))
+                               return mdbTable[cntxt->idx].brkCmd[i];
+       }
+       return 0;
+}
+
+/*
+ * Break points can be set on assignment to a specific variable,
+ * specific operation, or a instruction line
+*/
+void
+mdbSetBreakRequest(Client cntxt, MalBlkPtr mb, str request, char cmd)
+{
+       int i;
+       str modnme, fcnnme;
+       mdbState mdb = mdbTable + cntxt->idx;
+       Symbol sym;
+
+       /* set breakpoint on specific line */
+       if( *request == '#' ){
+               i= atoi(request+1);
+               if( i<0 || i>= mb->stop)
+                       mnstr_printf(cntxt->fdout, "breakpoint on #%d (<%d) not 
set\n", 
+                               i, mb->stop);
+               else  {
+                       mdb->brkBlock[mdb->brkTop] = mb;
+                       mdb->brkPc[mdb->brkTop] = i;
+                       mdb->brkVar[mdb->brkTop] = -1;
+                       mdb->brkMod[mdb->brkTop] = 0;
+                       mdb->brkFcn[mdb->brkTop] = 0;
+                       mdb->brkRequest[mdb->brkTop] = GDKstrdup(request);
+                       mdb->brkCmd[mdb->brkTop] = cmd;
+                       if (mdb->brkTop + 1 < MAXBREAKS)
+                               mdb->brkTop++;
+               }
+               return;
+       }
+
+       /* check for a [module.]function request */
+       fcnnme= strchr(request,'.');
+       if( fcnnme){
+               modnme= request;
+               *fcnnme= 0;
+               fcnnme++;
+               sym= findSymbol(cntxt->nspace, modnme,fcnnme);
+               mdb->brkBlock[mdb->brkTop] = sym? sym->def: mb;
+               mdb->brkPc[mdb->brkTop] = -1;
+               mdb->brkVar[mdb->brkTop] = -1;
+               mdb->brkMod[mdb->brkTop] = putName(modnme,strlen(modnme));
+               mdb->brkFcn[mdb->brkTop] = putName(fcnnme,strlen(fcnnme));
+               fcnnme--; *fcnnme= '.';
+               mdb->brkRequest[mdb->brkTop] = GDKstrdup(request);
+               mdb->brkCmd[mdb->brkTop] = cmd;
+               if (mdb->brkTop + 1 < MAXBREAKS)
+                       mdb->brkTop++;
+               return;
+       } 
+       /* the final step is to break on a variable */
+       i= findVariable(mb,request);
+       if( i< 0)
+               mnstr_printf(cntxt->fdout, "breakpoint on %s not set\n", 
request);
+       else {
+               mdb->brkBlock[mdb->brkTop] = mb;
+               mdb->brkPc[mdb->brkTop] = -1;
+               mdb->brkVar[mdb->brkTop] = i;
+               mdb->brkMod[mdb->brkTop] = 0;
+               mdb->brkFcn[mdb->brkTop] = 0;
+               mdb->brkRequest[mdb->brkTop] = GDKstrdup(request);
+               mdb->brkCmd[mdb->brkTop] = cmd;
+               if (mdb->brkTop + 1 < MAXBREAKS)
+                       mdb->brkTop++;
+       }
+}
+
+/* A breakpoint should be set once for each combination */
+void
+mdbSetBreakpoint(Client cntxt, MalBlkPtr mb, int pc, char cmd)
+{
+       mdbState mdb = mdbTable + cntxt->idx;
+       char buf[20];
+
+       snprintf(buf,20,"#%d",pc);
+       mdb->brkBlock[mdb->brkTop] = mb;
+       mdb->brkPc[mdb->brkTop] = pc;
+       mdb->brkVar[mdb->brkTop] = -1;
+       mdb->brkMod[mdb->brkTop] = 0;
+       mdb->brkFcn[mdb->brkTop] = 0;
+       mdb->brkRequest[mdb->brkTop] = GDKstrdup(buf);
+       mdb->brkCmd[mdb->brkTop] = cmd;
+       if (mdb->brkTop + 1 < MAXBREAKS)
+               mdb->brkTop++;
+}
+
+void
+mdbShowBreakpoints(Client cntxt)
+{
+       int i;
+       mdbState mdb = mdbTable + cntxt->idx;
+
+       for (i = 0; i < mdb->brkTop; i++)
+               mnstr_printf(cntxt->fdout, "breakpoint on '%s'\n", 
mdb->brkRequest[i]);
+}
+
+static void
+mdbClrBreakpoint(Client cntxt, int pc)
+{
+       int i, j = 0;
+       mdbState mdb = mdbTable + cntxt->idx;
+
+       for (i = 0; i < mdb->brkTop; i++) {
+               mdb->brkBlock[j] = mdb->brkBlock[i];
+               mdb->brkPc[j] = mdb->brkPc[i];
+               mdb->brkVar[j] = mdb->brkVar[i];
+               mdb->brkMod[j] = mdb->brkMod[i];
+               mdb->brkFcn[j] = mdb->brkFcn[i];
+               mdb->brkRequest[j] = mdb->brkRequest[i];
+               mdb->brkCmd[j] = mdb->brkCmd[i];
+               if (mdb->brkPc[i] != pc)
+                       j++;
+               else {
+                       GDKfree(mdb->brkRequest[i]);
+                       mdb->brkRequest[i] = 0;
+               }
+
+       }
+       mdb->brkTop = j;
+}
+
+void
+mdbClrBreakRequest(Client cntxt, str request)
+{
+       int i, j = 0;
+       mdbState mdb = mdbTable + cntxt->idx;
+
+       for (i=0; i < mdb->brkTop; i++) {
+               mdb->brkBlock[j] = mdb->brkBlock[i];
+               mdb->brkPc[j] = mdb->brkPc[i];
+               mdb->brkVar[j] = mdb->brkVar[i];
+               mdb->brkMod[j] = mdb->brkMod[i];
+               mdb->brkFcn[j] = mdb->brkFcn[i];
+               mdb->brkRequest[j] = mdb->brkRequest[i];
+               mdb->brkCmd[j] = mdb->brkCmd[i];
+               if (strcmp(mdb->brkRequest[i], request))
+                       j++;
+               else {
+                       GDKfree(mdb->brkRequest[i]);
+                       mdb->brkRequest[i] = 0;
+               }
+       }
+       mdb->brkTop = j;
+}
+
+int
+mdbSetTrap(Client cntxt, str modnme, str fcnnme, int flag){
+       Symbol s;
+       s = findSymbol( cntxt->nspace, putName(modnme, strlen(modnme)),
+                                       putName(fcnnme, strlen(fcnnme)));
+       if (s == NULL)
+               return -1;
+       while ( s) {
+               s->def->trap = flag;
+               s= s->peer;
+    }
+       return 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_DEBUG);
+       mnstr_printf(cntxt->fdout, "#%s at %s.%s[%d]\n", msg, 
+               getModuleId(getInstrPtr(mb,0)),
+               getFunctionId(getInstrPtr(mb,0)),pc);
+       GDKfree(msg);
+}
+
+/* utility to display instruction and dispose of structure */
+void
+printTraceCall(stream *out, MalBlkPtr mb, MalStkPtr stk, int pc, int flags)
+{
+       str msg;
+       InstrPtr p;
+
+       p= getInstrPtr(mb,pc);
+       msg = instruction2str(mb, stk, p, flags);
+       mnstr_printf(out, "#%s%s\n", (mb->errors?"!":""), msg);
+       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;
+       }
+}
+/*
+ * Sometimes we may want to trace the changes applied to the
+ * BAT buffer pool and report them together with the MAL
+ * instruction where it happened.
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to