Thanks to Adriano's adroit hunch, I was able to suspect assertions as the culprit.
Indeed, the code block that was running when the mysterious Fail:
messages were printed did call an assertion like this:
Debug.Assert(myString.Length > 0);
Clearly, "Fail:" is meant to be understood as "Assertion fail". I could verify this by changing it to:
Debug.Assert(myString.Length > 0, "Assertion failed with myString == \"" + myString + "\".");
This changed the Fail:
messages to Fail: Assertion failed with myString == ""
and dispelled the confusion, and gave me a handle on the problem for further debugging (since I know the assertion is the exact line generating the fail messages).
It turns out that in debug mode, Visual Studio does not break on assert failure but instead simply prints the failure message to the output (enabling breaks is discussed here). In my case, I had been using a trace listener so that my program's output would be printed to a file as well as the console. To do this, I used the following initialization code:
private static void PrepareListeners()
{
Trace.Listeners.Clear();
var logPath = "/path/to/my/file.txt";
File.Delete(logPath);
var textListener = new TextWriterTraceListener(logPath);
var consoleListener = new ConsoleTraceListener(false);
consoleListener.TraceOutputOptions = TraceOptions.DateTime;
Trace.Listeners.Add(textListener);
Trace.Listeners.Add(consoleListener);
Trace.AutoFlush = true;
}
And afterwards I had been producing output with Trace.WriteLine
. It would appears that the trace listeners are picking up the assertion failure messages, too. (They show up in my log file as well as the console.)