• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 329
  • Last Modified:

Reflection to a C++ application for exception handling? Possible? or Exception handling of a C++ app.

Hi there;

I have a C# example to catch the exception of C++ program (divide by zero). my aim is that I want to catch the exception of that C++ program but after it crashes, I don't want the human user to click the windows indicating the program failed, after that crash.

So, what I have done is that reflection but I didn't know reflection is only applicable for a C# program. So, when 2 programs are C# with the given scenario, it's OK but my case is that the target application is a C++ program.

So, how can I do this?

I feel to change the C++ code by modifying with this but, couldn't manage:

As seen, there is an API SetUnhandledExceptionFilter which can help to avoid popup a window for user mode exception
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680634(v=vs.85).aspx


So, could someone provide me a working code for this?

Kind regards.
0
jazzIIIlove
Asked:
jazzIIIlove
  • 15
  • 14
  • 2
9 Solutions
 
evilrixSenior Software Engineer (Avast)Commented:
>> So, how can I do this?
With standard C++ you can't, it doesn't have a concept of reflection. It does support RTTI, but this isn't really the same thing.
0
 
evilrixSenior Software Engineer (Avast)Commented:
Incidentally, "divide by zero" sounds very much like an SEH exception rather than a C++ exception.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx

This isn't the same as a C++ exception. It uses a Microsoft proprietary extension.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx
0
 
jazzIIIloveAuthor Commented:
so, reflection out of question?

But I have to catch the exception of that c++, div by zero (this exception is an example).

What I want is that I want to catch the exception of that C++ application with my C# application (wtih no human interaction (apart from running that C++ application)

and that C++ application's exception will be caught.

I believe that the only way is the modification of that C++ application. Is it true? If so, how? Any example code or?

Regards.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
jazzIIIloveAuthor Commented:
Btw;

I am excluding kernel exceptions.
0
 
jkrCommented:
Indeed that's a SEH thing which you could cover with such a filter you mentioned above.

>>I don't want the human user to click the windows indicating the program
>>failed, after that crash.

There's a surprisingly simple solution to that aspect: 'SetErrorMode()' (http://msdn.microsoft.com/en-us/library/ms680621(VS.85).aspx):
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

Open in new window

0
 
jazzIIIloveAuthor Commented:
Hmm,

I got confused.

So, should I do this in my C++ (target app) or C# app (that will handle the error by himself)?

Kind regards.
0
 
jkrCommented:
If you want to implement an exception handler (the less problem prone way), you'll have to do that in the C++ module, since SEH only works with unmanaged code, e.g.
LONG
WINAPI
MyExceptionHandler(LPEXCEPTION_POINTERS pe) {

    char acModule[MAX_PATH];

    MEMORY_BASIC_INFORMATION mbi;
    HMODULE hMod;

    if (EXCEPTION_INT_DIVIDE_BY_ZERO != pe->ExceptionRecord.ExceptionCode) return EXCEPTION_EXECUTE_HANDLER; // don't handle

    VirtualQuery (pe->ExceptionRecord->ExceptionAddress,&mbi,sizeof(mbi));

    ptrdiff_t RVA = (char*)pe->ExceptionRecord->ExceptionAddress - (char*)mbi.AllocationBase;

    hMod = (HMODULE) mbi.AllocationBase;

    GetModuleFileName(hMod,acModule,sizeof (acModule));

    printf( "Detected EXCEPTION_INT_DIVIDE_BY_ZERO in %s at RVA 0x%08X\n", acModule, RVA);

    return EXCEPTION_EXECUTE_HANDLER;
}

Open in new window


'SetErrorMode()' would more be 'cosmetics' so that the user never gets notified about these errors (yet that could be called from C# also if we're talking about one single process)
0
 
jazzIIIloveAuthor Commented:
But, should I put this for the main method of the C++ program or how can I integrate this with a simple hello world C++ program?

Kind regards.
0
 
jkrCommented:
Well, the best would be to install the exception handler in the entry point of your module, e.g.
BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
)
{

  if (DLL_PROCESS_ATTACH == fdwReason) SetUnhandledExceptionFiter(MyExceptionHandler);

  return TRUE;
}

Open in new window

0
 
jazzIIIloveAuthor Commented:
Ah, could u put this into this as i am illiterate about puttung this;

int main(){
printf("Hello world");
int x = 0;
Int y = 1 / x;
printf("%d\n", y);
return 0;
}

Regards, and how am i going to catch this exception via my C# application?

Regards.
0
 
jkrCommented:
Sure ;o)
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

LONG
WINAPI
MyExceptionHandler(LPEXCEPTION_POINTERS pe) {

    char acModule[MAX_PATH];

    MEMORY_BASIC_INFORMATION mbi;
    HMODULE hMod;

    if (EXCEPTION_INT_DIVIDE_BY_ZERO != pe->ExceptionRecord.ExceptionCode) return EXCEPTION_EXECUTE_HANDLER; // don't handle

    VirtualQuery (pe->ExceptionRecord->ExceptionAddress,&mbi,sizeof(mbi));

    ptrdiff_t RVA = (char*)pe->ExceptionRecord->ExceptionAddress - (char*)mbi.AllocationBase;

    hMod = (HMODULE) mbi.AllocationBase;

    GetModuleFileName(hMod,acModule,sizeof (acModule));

    printf( "Detected EXCEPTION_INT_DIVIDE_BY_ZERO in %s at RVA 0x%08X\n", acModule, RVA);

    return EXCEPTION_EXECUTE_HANDLER;
}

int main(){

  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  SetUnhandledExceptionFiter(MyExceptionHandler);

  printf("Hello world");

  int x = 0;
  int y = 1 / x;
  printf("%d\n", y);

  return 0;
}

Open in new window


>>and how am i going to catch this exception via my C# application?

That depends - how are you running that app and how do you want to be notified about that?
0
 
jazzIIIloveAuthor Commented:
Just a simple C# console application, i just want to run with Process.Start(crashingC++programabove.exe somecmd argumentsfortheaboveC++program)

And Console.WriteLine("The C++ program crashes and the crash screen is purged automatically");

How?

Regards.
0
 
jkrCommented:
The easiest way might be via exit codes (as long as you can read them in C#, e.g.
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

LONG
WINAPI
MyExceptionHandler(LPEXCEPTION_POINTERS pe) {

    char acModule[MAX_PATH];

    MEMORY_BASIC_INFORMATION mbi;
    HMODULE hMod;

    if (EXCEPTION_INT_DIVIDE_BY_ZERO != pe->ExceptionRecord.ExceptionCode) return EXCEPTION_CONTINUE_HANDLER; // don't handle

    VirtualQuery (pe->ExceptionRecord->ExceptionAddress,&mbi,sizeof(mbi));

    ptrdiff_t RVA = (char*)pe->ExceptionRecord->ExceptionAddress - (char*)mbi.AllocationBase;

    hMod = (HMODULE) mbi.AllocationBase;

    GetModuleFileName(hMod,acModule,sizeof (acModule));

    printf( "Detected EXCEPTION_INT_DIVIDE_BY_ZERO in %s at RVA 0x%08X\n", acModule, RVA);

    ExitProcess(42); // indicate an exception

    return EXCEPTION_EXECUTE_HANDLER; // this now is mainly to make the compiler happy
}

int main(){

  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  SetUnhandledExceptionFiter(MyExceptionHandler);

  printf("Hello world");

  int x = 0;
  int y = 1 / x;
  printf("%d\n", y);

  return 0;  // regular exit code
}

Open in new window

0
 
jazzIIIloveAuthor Commented:
But, the trick is that u have to have a human interaction with exit codes...if the C++ app fails to execute for its exception, there is a pop up that human user must click for the popup that indicates the C++ application fails to execute, that's the reason exit code works for only working apps but not for the exception giving ones.

Regards.
0
 
jkrCommented:
No, certainly not: The exit code is read by the launching application (your C# app) when the launched application (the C++ part) is terminated - the user actually will never see any exit codes.
0
 
jazzIIIloveAuthor Commented:
But considering exception of the C++ program, the exit code won't help as the C++ application will go into an exception before the exit code arrives wurh a popup and the user must click to that OK button in that popup so as to have the popup to vanish. Isn't it? (which i don't want). I want that the exception of that C++ application vanishes without any human interaction preferably with my C# code or maybe C++ code. How to do that?

Regards.
0
 
jkrCommented:
No ;o)

The exception will be handled and the program terminates gracefully with the respective exit code. That's the whole point.
0
 
jazzIIIloveAuthor Commented:
So, not exception pop up of the C++ executable process when it runs from the very C# program below?

as I believe if there is the division by zero exception in C++ program, then my C# program goes into System.InvalidOperationException and the user must click the C++ crash screen of Debug or Close, which I don't want them to do (just I want the crashing window to vanish. The screenshot is as attached.


The code that I plan to use is as follows:

         startInfo.FileName = "Crash.exe";
            startInfo.Arguments = " " + "some command line arguments";                                    
                try
                {
                    exeProcess = Process.Start(startInfo);
                    //0 success

                    //3 failure
                    //-2147483645 failure
                    //System.InvalidOperationException failure

                    exeProcess.WaitForExit();

                    if (exeProcess.ExitCode != 0)                  
                        //Logging
                        processLogTextBox.AppendText("C++ program crashed with exitcode " + exeProcess.ExitCode + "!\n");                    
                    else
                        //Logging
                        processRSATLogTextBox.AppendText("C++ program executed successfully with exitcode " + exeProcess.ExitCode + "!\n");
                }
...

Regards.
crashscreen.png
0
 
jkrCommented:
What is the exact code fot 'crash.exe'?
0
 
jazzIIIloveAuthor Commented:
A c++ code simply having divide by zero exception.

Regards.
0
 
jkrCommented:
Yes, but do you have

  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);


in there? Also, does
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int main(){

  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

  printf("Hello world");

  __try {

    int x = 0;
    int y = 1 / x;
    printf("%d\n", y);

  } __except(1) {

    return 42;
  }

  return 0;  // regular exit code
}

Open in new window


work?
0
 
jazzIIIloveAuthor Commented:
Hi jkr;

Thanks for your interest. I made it working with division by zero, but I have final questions to finalize this question.

First of all, thanks for your effort. Now;

I didn't use the exception handler function you provide in a above comment of yours (the attached code I am talking about). I didn't use it

//

But, I used the very above code of yours. So, what is the difference between those 2 codes?

//

Another issue is that

When I comment the SetErrorMode, the code of yours is also working without an issue. So what is the point of writing that line?

What I mean is that as follows:

int main(){
//what is the point of the following line? The program seems working without an issue without that line
      //SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

      //printf("Hello world!\n");

      __try {

            int x = 0;
            int y = 1 / x;
            printf("%d\n", y);

      } __except(1) {

            return 42;
      }

      return 0;  // regular exit code
}

Finally and drastic question; will this implementation catch any other exception?

I mean, suppose that the c++ program goes into another exception, a db operartion issue maybe, so in such case, will the C# application catch the exception of C++ application as an exit code and moreover, still no interaction? (To rephrase I can say, will the above work for any exception (unforeseen)?)

Kind regards.
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

LONG
WINAPI
MyExceptionHandler(LPEXCEPTION_POINTERS pe) {

    char acModule[MAX_PATH];

    MEMORY_BASIC_INFORMATION mbi;
    HMODULE hMod;

    if (EXCEPTION_INT_DIVIDE_BY_ZERO != pe->ExceptionRecord.ExceptionCode) return EXCEPTION_CONTINUE_HANDLER; // don't handle

    VirtualQuery (pe->ExceptionRecord->ExceptionAddress,&mbi,sizeof(mbi));

    ptrdiff_t RVA = (char*)pe->ExceptionRecord->ExceptionAddress - (char*)mbi.AllocationBase;

    hMod = (HMODULE) mbi.AllocationBase;

    GetModuleFileName(hMod,acModule,sizeof (acModule));

    printf( "Detected EXCEPTION_INT_DIVIDE_BY_ZERO in %s at RVA 0x%08X\n", acModule, RVA);

    ExitProcess(42); // indicate an exception

    return EXCEPTION_EXECUTE_HANDLER; // this now is mainly to make the compiler happy
}

int main(){

  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  SetUnhandledExceptionFiter(MyExceptionHandler);

  printf("Hello world");

  int x = 0;
  int y = 1 / x;
  printf("%d\n", y);

  return 0;  // regular exit code
}

Open in new window

0
 
jkrCommented:
Well, to sum that up, 'SetErrorMode()' only manipulates the way Windows presents errors to users and therefore is merely a 'cosmetic' function.

Any SEH(!) exception that occurs within a SEH handler block like
//...

     __try {

            // guarded code

      } __except(1) {

            // handler
      }

Open in new window


will be handled in the '__except()' block (or not, depending what you do there).

The caveat still is that this and also any handler that is set via 'SetUnhandledExceptionFilter()' only affects SEH exceptions. C++ exceptions are completely different and both are hard to mix. You could do that byusing
void entry_point_for_actual_code() {

  // actual code goes here
}

void cpp_frame() {

  try {

    entry_point_for_actual_code();
  }
  catch(...) {

  }
}

void SEH_frame() {

     __try {

        cpp_frame();

      } __except(1) {

      }
}

int main () {

  SEH_frame();

  return 0;
}

Open in new window

0
 
jazzIIIloveAuthor Commented:
>> C++ exceptions are completely different and both are hard to mix. You could do that byusing

so this try except idea works for division by zero exceptions but fails for some other (most other) exceptions that can be in a C++ application? Is this what you say?

Regards and thanks for the patience.
0
 
jkrCommented:
I am trying to point out the defference between 'exception' and 'exception' here ;o)

For a list of exceptions covered by SEH, see http://msdn.microsoft.com/en-us/library/aa363082%28v=VS.85%29.aspx ("EXCEPTION_RECORD structure"). These are noably 'closer' to the OS. Then there are C++ exceptions, where it would be enough to use

throw 42;

to invoke a handler or terminate the program. With the possible multitude of exceptions that can be thrown in C++ (classes, even string litreals etc.) you will have to rely on a construct like  
try {

    //...
  }
  catch(...) { // catch anything

  }

Open in new window


to cover these.
0
 
jazzIIIloveAuthor Commented:
OK then,
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); shouldn't be commented then? Right?

Regards.
0
 
jkrCommented:
Well, that is just 'eye candy', it does not enable you to inform your other app about problems.
0
 
jazzIIIloveAuthor Commented:
Eye candy for whom? Me or my C# application which will grab that?

Regards.
0
 
jkrCommented:
'Eye candy' for the user - from the docs: "The SetErrorMode function controls whether the system will handle the specified types of serious errors, or whether the process will handle them."

IOW: It won't hurt...
0
 
jazzIIIloveAuthor Commented:
All in all, e.g. if the exception is e.g. a database exception (suppose the C++ app. tries to connect a database server, which is down), then will this be caught with this try-except?

I believe the kernel exceptions won't be caught (which I don't care) but what I care is that not only division by zero but also most exceptions in the c++ code should be caught.

So, try-except is a right option?

Kind regards.

P.S. I know I am asking too much, but this is the last question.
Thanks for your patience.
0
 
jkrCommented:
Well, if you take the last example putting on both a 'SEH_frame()' and a 'cpp_frame()' for catching exceptions before transferring the control flow to the rest of the code - yes, that should be enough (at least I hope that I did not miss anything).
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 15
  • 14
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now