[svn:mod_parrot] rev 169 - in mod_parrot/trunk: . lib/ModParrot
[email protected] 19 Jul 2005 15:43:28 -0000
Newsgroups
perl.cvs.mod_parrot
Message-ID
<[email protected] >
Author: jhorwitz
Date: Tue Jul 19 08:43:28 2005
New Revision: 169
Modified:
mod_parrot/trunk/call_list.txt
mod_parrot/trunk/lib/ModParrot/init.imc
mod_parrot/trunk/nci.c
mod_parrot/trunk/parrot_util.c
Log:
add ModParrot::NCI::backtrace to return backtraces in a string
Modified: mod_parrot/trunk/call_list.txt
==============================================================================
--- mod_parrot/trunk/call_list.txt (original)
+++ mod_parrot/trunk/call_list.txt Tue Jul 19 08:43:28 2005
@@ -6,6 +6,7 @@ i tp
v tiiiptt
i Pip
p J
+t J
t Jp
t Jpt
i Jp
Modified: mod_parrot/trunk/lib/ModParrot/init.imc
==============================================================================
--- mod_parrot/trunk/lib/ModParrot/init.imc (original)
+++ mod_parrot/trunk/lib/ModParrot/init.imc Tue Jul 19 08:43:28 2005
@@ -23,6 +23,9 @@
null nul
+ dlfunc func, nul, "mpnci_backtrace", "tJ"
+ store_global "ModParrot::NCI", "backtrace", func
+
dlfunc func, nul, "mpnci_request_rec", "pJ"
store_global "ModParrot::NCI", "request_rec", func
Modified: mod_parrot/trunk/nci.c
==============================================================================
--- mod_parrot/trunk/nci.c (original)
+++ mod_parrot/trunk/nci.c Tue Jul 19 08:43:28 2005
@@ -171,3 +171,8 @@ int mpnci_rwrite(Parrot_Interp interp, P
return(bytes);
}
+
+char *mpnci_backtrace(Parrot_Interp interp)
+{
+ return (char *)modparrot_backtrace(interp);
+}
Modified: mod_parrot/trunk/parrot_util.c
==============================================================================
--- mod_parrot/trunk/parrot_util.c (original)
+++ mod_parrot/trunk/parrot_util.c Tue Jul 19 08:43:28 2005
@@ -100,3 +100,66 @@ int modparrot_call_sub_IS(Parrot_Interp
*ret = Parrot_call_sub_ret_int(interp, sub, "IS", MAKE_PARROT_STRING(arg));
return(1);
}
+
+/* adapted from Parrot's PDB_backtrace */
+char *modparrot_backtrace(Parrot_Interp interp)
+{
+ STRING *str, *buf = NULL;
+ PMC *sub;
+ PMC *old = PMCNULL;
+ int rec_level = 0;
+ parrot_context_t ctx;
+ char *trace_string;
+
+ /* information about the current sub */
+ sub = interpinfo_p(interp, CURRENT_SUB);
+ if (!PMC_IS_NULL(sub)) {
+ str = Parrot_Context_infostr(interp, &interp->ctx);
+ if (str)
+ buf = string_concat(interp, buf, str, 0);
+ }
+
+ /* backtrace: follow the continuation chain */
+ ctx = interp->ctx;
+
+ while (1) {
+ sub = CONTEXT(ctx)->current_cont;
+ if (!sub)
+ break;
+ str = Parrot_Context_infostr(interp,
+ &PMC_cont(sub)->to_ctx);
+ if (!str)
+ break;
+
+ /* recursion detection */
+ if (!PMC_IS_NULL(old) && PMC_cont(old) &&
+ CONTEXT(PMC_cont(old)->to_ctx)->current_pc ==
+ CONTEXT(PMC_cont(sub)->to_ctx)->current_pc &&
+ CONTEXT(PMC_cont(old)->to_ctx)->current_sub ==
+ CONTEXT(PMC_cont(sub)->to_ctx)->current_sub) {
+ ++rec_level;
+ } else if (rec_level != 0) {
+ string_nprintf(interp, buf, 0, "... call repeated %d times\n",
+ rec_level);
+ buf = string_concat(interp, buf, str, 0);
+ rec_level = 0;
+ }
+
+ /* print the context description */
+ if (rec_level == 0)
+ buf = string_concat(interp, buf, str, 0);
+
+ /* get the next Continuation */
+ ctx = PMC_cont(sub)->to_ctx;
+ old = sub;
+ if (!ctx.rctx || !CONTEXT(ctx)->prev)
+ break;
+ }
+ if (rec_level != 0) {
+ string_nprintf(interp, buf, 0, "... call repeated %d times\n",
+ rec_level);
+ }
+
+ trace_string = string_to_cstring(interp, buf);
+ return(trace_string);
+}