aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-04-18 07:36:27 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-04-18 07:36:27 +0000
commit626bca37562b1a70eb657faa1c1827856fae85eb (patch)
tree6ee012b87c3e7f3ba3ec6e94e22ac7fa82f6ba29
parent79fafa2bcce3f41fe044d3ebd86f071304bac36f (diff)
downloadmailfromd-626bca37562b1a70eb657faa1c1827856fae85eb.tar.gz
mailfromd-626bca37562b1a70eb657faa1c1827856fae85eb.tar.bz2
Sync with trunk
git-svn-id: file:///svnroot/mailfromd/branches/alpha_3_1_91_berkeley_txn@1364 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog10
-rw-r--r--NEWS25
-rw-r--r--mflib/heloarg_test.mf4
-rw-r--r--mflib/match_cidr.mf2
-rw-r--r--mflib/match_dnsbl.mf4
-rw-r--r--mflib/match_rhsbl.mf4
-rw-r--r--mflib/spf.mf2
-rw-r--r--mflib/valid_domain.mf2
-rw-r--r--src/bi_other.m46
-rw-r--r--src/gram.y6
-rw-r--r--src/mailfromd.h1
-rw-r--r--src/main.c16
-rw-r--r--src/prog.c50
13 files changed, 119 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 00ed8a3d..98be13da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-04-18 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * src/gram.y (apply_deferred_init): Fix error messages
+ * src/mailfromd.h, src/prog.c, src/main.c, src/bi_other.m4,
+ NEWS: Implement stack traces.
+
+ * mflib/match_dnsbl.mf, mflib/heloarg_test.mf,
+ mflib/valid_domain.mf, mflib/match_rhsbl.mf, mflib/spf.mf,
+ mflib/match_cidr.mf, doc/mailfromd.texi: Use <> in #include
+
2007-04-17 Sergey Poznyakoff <gray@gnu.org.ua>
* src/mu_dbm.c, src/mu_dbm.h: Use transactions for providing
diff --git a/NEWS b/NEWS
index a86344b8..e7a0a545 100644
--- a/NEWS
+++ b/NEWS
@@ -82,6 +82,31 @@ to the logs, notifying of the new stack size, e.g.:
You can use these messages to adjust your stack size configuration
settings.
+* Runtime stack traces
+
+New command line option --stack-trace enables dumping stack traces
+on runtime errors. This might help localize the source of the error.
+The trace looks like:
+
+mailfromd: RUNTIME ERROR near ../mflib/match_cidr.mf:30: invalid CIDR (boo%)
+mailfromd: Stack trace:
+mailfromd: 0077: test.mf:7: match_cidr
+mailfromd: 0096: test.mf:13: bar
+mailfromd: 0110: test.mf:18: foo
+mailfromd: Stack trace finishes
+mailfromd: Execution of the configuration program was not finished
+
+Each trace line describes one stack frame, the lines appear in the
+order of most recently called to least recently called. Each frame
+consists of:
+
+1. Value of program counter at the time of its execution
+2. Source code location, if available
+3. Name of the function called
+
+The same output can be obtained by calling function stack_trace()
+in your filter program.
+
* connect handler
Connect handler is implemented.
diff --git a/mflib/heloarg_test.mf b/mflib/heloarg_test.mf
index 48587d39..840d38f0 100644
--- a/mflib/heloarg_test.mf
+++ b/mflib/heloarg_test.mf
@@ -16,8 +16,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
-#include_once "is_ip.mf"
-#include_once "dns.mf"
+#include_once <is_ip.mf>
+#include_once <dns.mf>
const HELO_SUCCESS 0
const HELO_MYIP 1 # ARG is our IP address.
diff --git a/mflib/match_cidr.mf b/mflib/match_cidr.mf
index 92b7248a..e79b6586 100644
--- a/mflib/match_cidr.mf
+++ b/mflib/match_cidr.mf
@@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
-#include_once "status.mfh"
+#include_once <status.mfh>
#pragma regex push +extended
diff --git a/mflib/match_dnsbl.mf b/mflib/match_dnsbl.mf
index a361e156..585d6fe1 100644
--- a/mflib/match_dnsbl.mf
+++ b/mflib/match_dnsbl.mf
@@ -16,8 +16,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
-#include_once "dns.mf"
-#include_once "match_cidr.mf"
+#include_once <dns.mf>
+#include_once <match_cidr.mf>
#pragma regex push +extended
diff --git a/mflib/match_rhsbl.mf b/mflib/match_rhsbl.mf
index 4bb855c9..f97e2bcc 100644
--- a/mflib/match_rhsbl.mf
+++ b/mflib/match_rhsbl.mf
@@ -16,8 +16,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
-#include_once "dns.mf"
-#include_once "match_cidr.mf"
+#include_once <dns.mf>
+#include_once <match_cidr.mf>
#pragma regex push +extended
func match_rhsbl(string email, string zone, string range)
diff --git a/mflib/spf.mf b/mflib/spf.mf
index 5a1c737e..eacaa5a6 100644
--- a/mflib/spf.mf
+++ b/mflib/spf.mf
@@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
-#include_once "safedb.mf"
+#include_once <safedb.mf>
#pragma regex push +extended +icase
set spf_database "%__statedir__/spf.db"
diff --git a/mflib/valid_domain.mf b/mflib/valid_domain.mf
index bb49e924..d511e7eb 100644
--- a/mflib/valid_domain.mf
+++ b/mflib/valid_domain.mf
@@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
-#include_once "dns.mf"
+#include_once <dns.mf>
# boolean valid_domain (string DOMAIN)
#
diff --git a/src/bi_other.m4 b/src/bi_other.m4
index 5c7ed7d3..94e3e029 100644
--- a/src/bi_other.m4
+++ b/src/bi_other.m4
@@ -112,4 +112,10 @@ MF_DEFUN(cancel_program_trace, VOID, STRING name)
}
END
+MF_DEFUN(stack_trace, VOID)
+{
+ runtime_stack_trace(env);
+}
+END
+
MF_INIT
diff --git a/src/gram.y b/src/gram.y
index 24fab3a2..4a308411 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -3470,13 +3470,13 @@ apply_deferred_init()
for (p = deferred_decl; p; p = p->next) {
struct variable *var = variable_lookup(p->name->text);
if (!var) {
- mu_error("<command line>: warning: no such variable %s",
- p->name);
+ mu_error("<command line>: warning: no such variable: %s",
+ p->name->text);
continue;
}
if (initialize_variable(var, &p->value, get_locus()))
mu_error("error initialising variable %s: incompatible types",
- p->name);
+ p->name->text);
}
}
diff --git a/src/mailfromd.h b/src/mailfromd.h
index c09f834b..23574182 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -275,6 +275,7 @@ extern int script_dump_xref;
extern size_t lock_retry_count_option;
extern time_t lock_retry_timeout_option;
extern char *mailfromd_state_dir;
+extern int stack_trace_option;
/* Configuration file parser */
diff --git a/src/main.c b/src/main.c
index d9be5103..450129fb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -92,7 +92,7 @@ time_t lock_retry_timeout_option = 1;
/* DBM-related options end */
int source_info_option; /* Debug messages include source locations */
-
+int stack_trace_option; /* Print stack traces on runtime errors */
char *file_option; /* File name for DB management commands */
struct db_format *format_option;
@@ -652,6 +652,12 @@ set_source_info(void *value)
source_info_option = (int) value;
}
+void
+set_stack_trace(void *value)
+{
+ stack_trace_option = (int) value;
+}
+
static void
set_lock_retry_count(void *value)
{
@@ -844,6 +850,7 @@ struct option_cache {
{ "ehlo", NULL, option_ehlo, set_ehlo },
{ "debug", NULL, option_debug, set_debug },
{ "source-info", NULL, option_boolean, set_source_info },
+ { "stack-trace", NULL, option_boolean, set_stack_trace },
{ "expire-interval", NULL, option_time, set_expire },
{ "positive-expire-interval", NULL, option_time, set_positive_expire },
{ "negative-expire-interval", NULL, option_time, set_negative_expire },
@@ -939,6 +946,7 @@ enum mailfromd_option {
OPTION_PREDICT_NEXT,
OPTION_SHOW_DEFAULTS,
OPTION_SINGLE_PROCESS,
+ OPTION_STACK_TRACE,
OPTION_SOURCE_INFO,
OPTION_SYSLOG,
OPTION_TIME_FORMAT,
@@ -1085,6 +1093,8 @@ static struct argp_option options[] = {
N_("Set the identifier used in syslog messages to STRING"), GRP+1 },
{ "source-info", OPTION_SOURCE_INFO, NULL, 0,
N_("Debug messages include source information"), GRP+1 },
+ { "stack-trace", OPTION_STACK_TRACE, NULL, 0,
+ N_("Enable stack traces on runtime errors"), GRP+1 },
#undef GRP
/*DEPRECATED OPTIONS*/
@@ -1347,6 +1357,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
single_process_option = 1;
break;
+ case OPTION_STACK_TRACE:
+ set_option("stack-trace", "yes", 1);
+ break;
+
case OPTION_SOURCE_INFO:
set_option("source-info", "yes", 1);
break;
diff --git a/src/prog.c b/src/prog.c
index 720cef89..a29e1979 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -358,6 +358,54 @@ prog_trace(eval_environ_t env, const char *fmt, ...)
buf);
}
+void instr_funcall(eval_environ_t env);
+void instr_locus(eval_environ_t env);
+
+void
+runtime_stack_trace(eval_environ_t env)
+{
+ size_t base;
+
+ mu_error("Stack trace:");
+ for (base = env->base; base < datasize + env->stack_size - 4;
+ base = (size_t) env->dataseg[base + 1] + base + 1) {
+ int i;
+ prog_counter_t pc = (prog_counter_t)env->dataseg[base + 2] - 1;
+ char *name;
+ struct locus *ploc = NULL, loc;
+
+ if (prog[pc-2] == instr_funcall) {
+ name = (char*)(env->dataseg + (size_t) prog[pc-1]);
+ pc -= 2;
+ } else {
+ name = "(in catch)";
+ pc -= 3;
+ }
+
+ for (i = 0; i < 10; i++) {
+ if (pc > i + 3
+ && prog[pc - i - 3] == instr_locus) {
+ loc.file = (char*)(env->dataseg
+ + (size_t) prog[pc - i - 2]);
+ loc.line = (size_t) prog[pc - i - 1];
+ ploc = &loc;
+ break;
+ }
+ }
+
+ if (ploc)
+ mu_error("%04d: %s:%lu: %s",
+ (unsigned long) pc,
+ ploc->file, (unsigned long) ploc->line,
+ name);
+ else
+ mu_error("%04d: %s",
+ (unsigned long) pc,
+ name);
+ }
+ mu_error("Stack trace finishes");
+}
+
void
runtime_warning(eval_environ_t env, const char *fmt, ...)
{
@@ -386,6 +434,8 @@ runtime_error(eval_environ_t env, const char *fmt, ...)
vsnprintf(buf + n, sizeof buf - n, fmt, ap);
va_end(ap);
mu_error(buf);
+ if (stack_trace_option)
+ runtime_stack_trace(env);
env->status = SMFIS_TEMPFAIL; /* FIXME */
longjmp(env->x_jmp, 1);
}

Return to:

Send suggestions and report system problems to the System administrator.