Displaying debug messages coming from LibraryLink

When extending Mathematica through C or C++ code using the LibraryLink API, one common annoyance is that it’s not possible to see messages that the C code sends to stdout or stderr when using the graphical interface. While there are ways to send output directly to the active Mathematica notebook, often the C code is not written to be used exclusively with Mathematica and it simply prints debug messages to stderr. Standard C assertion failures also cause messages to be printed to stderr.

Here I will show how to view the Mathematica kernel’s output in a terminal window, even when using the graphical notebook interface.

On OS X, first we need to create a shell script which will launch the Mathematica kernel in a Terminal.app window. Put the following in a file named term_math and edit the path to Mathematica’s location on the do script line:

#!/bin/sh
# term_math

ARGS="$@"

osascript 2>&1>/dev/null <<EOF
  tell application "Terminal"
    do script ("'/Applications/Mathematica 10.app/Contents/MacOS/MathKernel' ${ARGS}; exit")
  end tell
EOF

Open a terminal and make the script executable using the chmod a+x term_math command.

Now we need to create a new kernel configuration: in Mathematica, choose Evaluation → Kernel Configuration Options…, then add a configuration as follows:

Be sure to use the correct and full path to the term_math script. It will be different on your system than on mine.

On Windows systems the procedure is similar, but simpler: we don’t need to create a custom script, just use the math.exe executable instead of math_term in the kernel configuration. On Windows, Mathematica comes with two versions of the kernel executable: one that always runs in a visible command window, math.exe, and one that is able to run without any visible windows, MathKernel.exe.

To use this special kernel configuration, just set it as the active notebook’s kernel using Evaluation → Notebook’s Kernel → …

Finally, we need to make sure that any messages that the C code prints will be output immediately instead of staying buffered. After printing any output in C/C++ code, it is important to flush the output buffer, otherwise the messages may not show up in the terminal until the kernel quits. In C this can be done using fflush(). When using C++ and <iostreams> , it’s usually more convenient to simply use std::endl to trigger flushing, for example std::cout << "some debug message" << std::endl;. Alternatively, std::cout.flush(); works as well.

Here’s a quick way to test that everything works as it should:

Needs["CCompilerDriver`"]

src = "
#include \"WolframLibrary.h\"
#include <stdio.h>

DLLEXPORT mint WolframLibrary_getVersion(){ return WolframLibraryVersion; }

DLLEXPORT int WolframLibrary_initialize(WolframLibraryData libData) { return 0; }

DLLEXPORT void WolframLibrary_uninitialize(WolframLibraryData libData) { return; }

DLLEXPORT int message_test(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    printf(\"Test message\\n\");
    fflush(stdout);
    return LIBRARY_NO_ERROR;
}
";

lib = CreateLibrary[src, "MessageTest"]

messageTest = LibraryFunctionLoad[lib, "message_test", {}, "Void"]

messageTest[]

Evaluating this code with our special kernel configuration will produce the following:

I find this technique invaluable when writing LibraryLink code, especially when I need to keep it as independent from Mathematica as possible, or when using libraries that print their own debugging messages.

Comments !