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