views:

71

answers:

2

I'm trying to write a program to test student code against a good implementation. I have a C++ console app that will run one test at a time determined by the command line args and a C# .net forms app that calls the c++ app once for each test. The goal is to be able to detect not just pass/fail for each test, but also "infinite" (>5secs) loop and exceptions (their code dying for whatever reason).

The problem is that not all errors kill the C++ app. If they corrupt the heap the system calls __debugbreak which pops up a window saying Debug Error! HEAP CORRUPTION DETECTED... My C# app is using Process.WaitForExit(5000) to wait, but this error doesn't count as an exit, so I see a timeout.

So my question is, how can I either get the C# app to detect that this is an error OR how can I get the C++ app to die when this error occurs rather than giving a dialog box and asking if I want to debug?

Edit:
Here's the error that pops up: Debug Error

Here's the normal application failed dialog that pops up if I press retry in the previous dialog: Windows Error. The debug option goes away if you turn off the JIT debugger.

+1  A: 

You should turn of JIT debugging, this page has instructions for how to turn it on or off.

Edit You can also use the _CrtSetReportMode and _CrtSetReportFile functions inside the C++ program to change the behaviour of the debug asserts (in particular, you can use _CRTDBG_MODE_FILE to write the contents of the message to a file instead of popping up a dialog.

If you're compiling the program as part of your tests, then you can just add your own .cpp file which includes a global class that does the work in it's constructor. Something like this:

// AssertModify.cpp
class AssertModify
{
public:
    AssertModify()
    {
        ::_CrtSetReportMode(...);
        ::_CrtSetReportFile(...);
    }
};

AssertModify am;

This'll cause the code to run before main() is entered which should catch all possible cases (unless the student overrides your value themselves, but you can add a check for any calls to _CrtSetReportMode in their submitted code before you compile it)

Dean Harding
The JIT debugging only happens after the process is good and dead. My error message is popping up before the process dies, which is why Process.WaitForExit isn't returning.
Cypher2100
I see, yes you're right. I've updated my answer with some additional info that should help you :)
Dean Harding
Thank you. This is exactly the thing I was looking for.
Cypher2100
A: 

I think you need to compile the C++ app in "release" mode. You're probably running "debug" builds which include asserts. Those asserts pop up MessageBoxes which is what you're seeing.

Since you want to catch the assertion failures, you can either modify the code when compiling it (as codeka suggests) or run the programs under a debugger. It's not that hard to make a C# app into a debugger using Mike Stall's wrapper, but it isn't exactly the easiest solution.

Gabe
You're right, I am running "debug" builds. If I use "release" mode then the errors don't happen, but then everything looks like it worked fine. I was hoping for some way of detected the assertions or overriding their behavior either within the c++ or from the c# side.
Cypher2100