diff --git a/src/libged/exec.cpp b/src/libged/exec.cpp index 15dac3aae0..0414ac99df 100644 --- a/src/libged/exec.cpp +++ b/src/libged/exec.cpp @@ -91,6 +91,17 @@ ged_exec(struct ged *gedp, int argc, const char *argv[]) GED_CK_MAGIC(gedp); Ged_Internal *gedip = gedp->i->i; gedip->exec_stack.push(cmdname); + gedip->cmd_recursion_depth_cnt[cmdname]++; + + if (gedip->cmd_recursion_depth_cnt[cmdname] > GED_CMD_RECURSION_LIMIT) { + bu_vls_printf(gedp->ged_result_str, "Recursion limit %d exceeded for command %s - aborted. ged_exec call stack:\n", GED_CMD_RECURSION_LIMIT, cmdname.c_str()); + std::stack lexec_stack = gedip->exec_stack; + while (!lexec_stack.empty()) { + bu_vls_printf(gedp->ged_result_str, "%s\n", lexec_stack.top().c_str()); + lexec_stack.pop(); + } + return BRLCAD_ERROR; + } // Check for a pre-exec callback. bu_clbk_t f = NULL; @@ -114,6 +125,7 @@ ged_exec(struct ged *gedp, int argc, const char *argv[]) if (tstr) bu_log("%s time: %g\n", cmdname.c_str(), (bu_gettime() - start)/1e6); + gedip->cmd_recursion_depth_cnt[cmdname]--; gedip->exec_stack.pop(); return cret; } @@ -128,6 +140,7 @@ ged_exec(struct ged *gedp, int argc, const char *argv[]) if (tstr) bu_log("%s time: %g\n", cmdname.c_str(), (bu_gettime() - start)/1e6); + gedip->cmd_recursion_depth_cnt[cmdname]--; gedip->exec_stack.pop(); return cret; } diff --git a/src/libged/ged.cpp b/src/libged/ged.cpp index 4f340b37f8..7a915840bb 100644 --- a/src/libged/ged.cpp +++ b/src/libged/ged.cpp @@ -445,9 +445,9 @@ ged_clbk_exec(struct bu_vls *log, struct ged *gedp, int limit, bu_clbk_t f, int Ged_Internal *gedip = gedp->i->i; int rlimit = (limit > 0) ? limit : 1; - gedip->recursion_depth_cnt[f]++; + gedip->clbk_recursion_depth_cnt[f]++; - if (gedip->recursion_depth_cnt[f] > rlimit) { + if (gedip->clbk_recursion_depth_cnt[f] > rlimit) { if (log) { // Print out ged_exec call stack that got us here. If the // recursion is all in callback functions this won't help, but at @@ -462,9 +462,10 @@ ged_clbk_exec(struct bu_vls *log, struct ged *gedp, int limit, bu_clbk_t f, int return BRLCAD_ERROR; } + // Checks complete - actually run the callback int ret = (*f)(ac, av, u1, u2); - gedip->recursion_depth_cnt[f]++; + gedip->clbk_recursion_depth_cnt[f]++; return ret; } diff --git a/src/libged/ged_private.h b/src/libged/ged_private.h index a6a6ef165f..8ec3d4bee0 100644 --- a/src/libged/ged_private.h +++ b/src/libged/ged_private.h @@ -56,7 +56,8 @@ class Ged_Internal { std::map> cmd_postrun_clbk; std::map> cmd_linger_clbk; - std::map recursion_depth_cnt; + std::map clbk_recursion_depth_cnt; + std::map cmd_recursion_depth_cnt; std::stack exec_stack;