diff: fix mdb I/O interleaving bug
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Feb 5 07:34:07 AEDT 1999
Estimated hours taken: 0.5
Fix a bug with I/O interleaving which was causing some of the
debugger test cases to fail.
trace/mercury_trace_internal.c:
Ensure that MR_mdb_err is unbuffered, and that we always
fflush(MR_mdb_out) before writing to MR_mdb_out.
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.21
diff -u -r1.21 mercury_trace_internal.c
--- mercury_trace_internal.c 1998/12/28 03:38:53 1.21
+++ mercury_trace_internal.c 1999/02/04 20:29:44
@@ -64,6 +64,13 @@
** the distinction between stdout and stderr: ordinary output, including
** information messages about conditions which are not errors, should
** go to MR_mdb_out, but error messages should go to MR_mdb_err.
+**
+** Note that MR_mdb_out and MR_mdb_err may both write to the same
+** file, so we need to be careful to ensure that buffering does
+** not stuff up the interleaving of error messages and ordinary output.
+** To ensure this, we do two things:
+** - MR_mdb_err is unbuffered
+** - we always fflush(MR_mdb_out) before writing to MR_mdb_err
*/
FILE *MR_mdb_in;
FILE *MR_mdb_out;
@@ -319,6 +326,9 @@
MR_mdb_out = MR_try_fopen(MR_mdb_out_filename, "w", stdout);
MR_mdb_err = MR_try_fopen(MR_mdb_err_filename, "w", stderr);
+ /* Ensure that MR_mdb_err is not buffered */
+ setvbuf(MR_mdb_err, NULL, _IONBF, 0);
+
if (getenv("MERCURY_SUPPRESS_MDB_BANNER") == NULL) {
fprintf(MR_mdb_out, MR_trace_banner, MR_VERSION);
}
@@ -389,6 +399,7 @@
static void
MR_trace_do_noop(void)
{
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"This command is a no-op from this port.\n");
}
@@ -451,6 +462,7 @@
problem = MR_trace_parse_line(line, &words, &word_max, &word_count);
if (problem != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "%s.\n", problem);
goto return_keep_interacting;
}
@@ -479,6 +491,7 @@
cmd->MR_trace_print_level = MR_default_print_level;
goto return_stop_interacting;
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "One of the first two words "
"must be a command.\n");
}
@@ -516,6 +529,7 @@
goto return_stop_interacting;
} else {
/* XXX this message is misleading */
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "The debugger cannot go "
"to a past event.\n");
}
@@ -775,6 +789,7 @@
MR_saved_curfr(saved_regs),
include_trace_data);
if (msg != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "%s.\n", msg);
}
} else {
@@ -824,6 +839,7 @@
MR_trace_internal_add_spy_point(when,
action, spy_proc, NULL);
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Ambiguous procedure "
"specification. "
@@ -845,6 +861,7 @@
MR_spy_points[n]->spy_enabled = TRUE;
MR_print_spy_point(n);
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Break point #%d does not exist.\n",
n);
@@ -868,6 +885,7 @@
MR_spy_points[n]->spy_enabled = FALSE;
MR_print_spy_point(n);
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Break point #%d does not exist.\n",
n);
@@ -879,6 +897,7 @@
}
if (MR_spy_point_next == 0) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"There are no break points yet.\n");
}
@@ -1050,6 +1069,7 @@
words[1]);
}
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Alias `%s' cannot be removed, "
"since it does not exist.\n",
@@ -1071,6 +1091,7 @@
} else {
msg = MR_trace_add_cat(words[2], slot, help_text);
if (msg != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Document category `%s' not added: "
"%s.\n", words[2], msg);
@@ -1090,6 +1111,7 @@
msg = MR_trace_add_item(words[1], words[3], slot,
help_text);
if (msg != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Document item `%s' in category `%s' "
"not added: %s.\n",
@@ -1230,6 +1252,7 @@
MR_trace_usage("misc", "quit");
}
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "Unknown command `%s'. "
"Give the command `help' for help.\n", words[0]);
}
@@ -1458,7 +1481,7 @@
MR_trace_usage(const char *cat, const char *item)
/* cat is unused now, but could be used later */
{
-
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"mdb: %s: usage error -- type `help %s' for help.\n",
item, item);
@@ -1483,6 +1506,7 @@
call_label = entry->MR_sle_call_label;
if (call_label->MR_sll_var_count < 0) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Cannot perform retry, because information about "
"the input arguments is not available.\n");
@@ -1507,6 +1531,7 @@
input_args->MR_slvs_names[i], &succeeded);
if (! succeeded) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Cannot perform retry because the values of "
"some input arguments are missing.\n");
@@ -1662,12 +1687,14 @@
&base_sp, &base_curfr, &problem);
if (level_layout == NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "%s\n", problem);
return;
}
problem = MR_trace_validate_var_count(level_layout, &var_count);
if (problem != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
@@ -1692,6 +1719,7 @@
fprintf(MR_mdb_out, "Ancestor level set to %d.\n",
*ancestor_level);
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "%s.\n", problem);
}
}
@@ -1745,12 +1773,14 @@
&base_sp, &base_curfr, &problem);
if (level_layout == NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
problem = MR_trace_find_var(level_layout, var_spec, &which_var);
if (problem != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
@@ -1790,12 +1820,14 @@
&base_sp, &base_curfr, &problem);
if (level_layout == NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
problem = MR_trace_validate_var_count(level_layout, &var_count);
if (problem != NULL) {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
@@ -2201,6 +2233,7 @@
fclose(fp);
return TRUE;
} else {
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err, "%s: %s.\n", filename, strerror(errno));
return FALSE;
}
@@ -2387,6 +2420,7 @@
max_mr_num);
default:
+ fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"unknown command, "
"try again\n");
--
Fergus Henderson <fjh at cs.mu.oz.au> | "Binaries may die
WWW: <http://www.cs.mu.oz.au/~fjh> | but source code lives forever"
PGP: finger fjh at 128.250.37.3 | -- leaked Microsoft memo.
More information about the developers
mailing list