0

I have written a few C++ classes which employ a variety C++ libraries. I made a Windows Form project, and set it up to use my classes successfully. However, I recently made another C++ class and now I consistently get:

A first chance exception of type 'System.AccessViolationException' occurred in TEST_OCU.exe

which leads to:

 An unhandled exception of type 'System.TypeInitializationException' occurred in Unknown Module.
 Additional information: The type initializer for '<Module>' threw an exception.

The program hasn't even started running yet, and the new, problem-causing C++ class hasn't even been constructed yet. If I comment out the new call, and only have a pointer to this new C++ class, everything compiles just fine. BUT, if somewhere I do something like:

 if(new_class_ptr != NULL)
    new_class_ptr->SomeFunction()  //It doesn't matter what function this is

This will throw those violations again


Some facts:

  • Compiling and linking is fine, this seems to be a run-time problem.
  • My solution employs unmanaged C++ libraries and classes (that I have written), and one managed C++ Form.
  • So far I haven't had any problems, I've used a few C++ libraries successfully for a while. This is caused by a new C++ class I recently wrote.
  • The C++ class which causes these violations uses std::ifstream to read in a file. If I comment out the std::ifstream input_file(filename); my Forms project runs successfully.
  • If I use the C++ class in a simple Win32 project, it compiles and runs just fine with the std::ifstream.
  • I have a strong feeling it is related to this question

Could anyone offer any advice? Thank you


EDIT: I'm providing some parts of my form code I have. RTSPConnection works just fine, the offending class is RTPStream

public ref class Form1 : public System::Windows::Forms::Form
{
public:
  // ... Lots of generated code here ...

//Calls I've written
    private: static RTSPConnection * rtsp_connection_ = NULL; //This class works
    private: static RTPStream * rtp_connection_ = NULL; //This class does not
    bool streaming_;
    System::Threading::Thread^ streaming_thread_;

    private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
        if(rtsp_connection_ == NULL)
        {
            rtsp_connection_ = new RTSPConnection("rtsp://192.168.40.131:8554/smpte");
            streaming_ = false;
        }

            //if(rtp_connection_ == NULL)
            //   rtp_connection_ = new RTPStream("test");

    }

    private: System::Void Form1_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
        if(rtsp_connection_ != NULL)
            rtsp_connection_->StopStreaming();
    }

    private: System::Void button1_MouseClick(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
        if(!streaming_)
        {
            //Start Streaming
            streaming_thread_ = gcnew Thread(gcnew ThreadStart(&Form1::WorkerThreadFunc));
            streaming_thread_->Start();

            this->button1->Text = L"Stop Streaming";
            streaming_ = true;
        }
        else
        {
            //Stop Streaming
            if(rtsp_connection_ != NULL)
            rtsp_connection_->StopStreaming();

            //THIS CALL RIGHT HERE WILL THROW AN ACCESS VIOLATION
            if(rtp_connection_ != NULL)
                rtp_connection_->StopStreaming();
            this->button1->Text = L"Start Streaming";
             streaming_ = false;
        }
    }
 };
Community
  • 1
  • 1
Constantin
  • 16,812
  • 9
  • 34
  • 52
  • 1
    You'll need to debug it. Project + Properties, Debug tab, tick the "Enable unmanaged code debugging" option. Debug + Exceptions, tick the Thrown box for Win32 exceptions. – Hans Passant Jul 05 '12 at 17:27
  • Having trouble finding this, I am on VS2010. – Constantin Jul 05 '12 at 17:33
  • 1
    http://stackoverflow.com/questions/11091356/how-to-enable-debugging-of-visual-studio-c-called-from-c-sharp/11299987#11299987 – Hans Passant Jul 05 '12 at 17:38
  • Hans, I do not have a similar property page. My Windows Forms C++ project brings up the same C++ property page layout as my Win32 C++ project. I would like to mention that I have the "C++ Exception" and "Win 32 Exceptions" checked in Debug->Exceptions. – Constantin Jul 05 '12 at 17:42
  • 1
    Set the debugger type to "Mixed". – Hans Passant Jul 05 '12 at 17:53
  • Done, what am I looking for now? First exception thrown was an Access Violation. The highest level relating to my program is: `TEST_OCU.exe!::LanguageSupport::Initialize() Line 698 C++` – Constantin Jul 05 '12 at 17:55
  • An `AccessViolationException` probably means you're trying to dereference a `NULL` or uninitialised pointer somewhere in your C++ code. – millimoose Jul 05 '12 at 18:01
  • I would tend to agree but no break point are ever reached, this seems to be before the program has even entered main and all the classes are being loaded. – Constantin Jul 05 '12 at 18:06
  • It all hinges on this line: `std::ifstream input_file(filename);` where `filename` is a `std::string`. Even though that line is never reached at run-time, commenting that line out or changing it to `std::ifstream input_file();` removes the violations. `std::ifstream input_file;` does not work though. – Constantin Jul 05 '12 at 18:17
  • 1
    You get almost the same error in C# if you have static class members that depend on each other and they aren't initialised in the order you expect. In C++, if you had a static singleton and another static member that referred to it, you'd get this error when the module was initialised if the member was initialised before the singleton. Does your class or source file have any static data? – arx Jul 05 '12 at 18:27
  • Arx, it does... Let me take a deeper look into that. (Funny I initially thought it was this as well, but wrote it off when I commented out the `std::ifstream` constructor and it worked.) I would like to add, I wrote a work around using FILE and fread... but I'ld rather use c++ streams to read my files... – Constantin Jul 05 '12 at 18:33
  • `Form1` has static members but doesn't seem to do any static initialisation, which is what causes the problem. Does `RTPStream` do any static initialisation? – arx Jul 05 '12 at 19:28
  • Static initialization is done using `if(rtsp_connection_ == NULL)`. In unmanaged c++ this would be fine ... does this not work in managed? Unless I am confused on what static initialization means. I purposefully leave the RTPStream pointer equal to `NULL` to show that I don't need to instantiate an RTPStream class to cause an AccessViolation (note I ALWAYS check if pointers are NULL before using them.) – Constantin Jul 05 '12 at 19:34
  • Microsoft C++/CLI != standard C++. But this certainly looks OK: `static RTPStream *rtp_connection_ = NULL`. Q: are you sure there aren't any static classes in "RTPStream" that *aren't* pointers (i.e. that might inadvertantly be created at program startup)? – paulsm4 Jul 05 '12 at 19:49
  • Just checked, only POD, pointers, and a std::string. I would like to note, my program is running perfectly using a `FILE *fp` and `fread` approach in place of the `std::ifstream`. (I am not okay with this, I would like this to be in C++). Also thank you so much for being so responsive so far. – Constantin Jul 05 '12 at 19:52
  • By "static initialisation" I meant initialising a static member to something more complicated than NULL (like a class instance). And you're not doing that in `Form1`, but might be in `RTPStream`? – arx Jul 05 '12 at 20:14

1 Answers1

0

These two statements appear to contradict each other:

The program hasn't even started running yet, and the new, problem-causing C++ class hasn't even been constructed yet.

If I comment out the new call, and only have a pointer to this new C++ class, everything compiles just fine.

Q: Could you please post the code where you're calling "new"? Or are you calling "new" - perhaps you just meant "if I comment out my new class"?

Q: Could you please set a breakpoint in your constructor, look at the stack trace, and see who's invoking it? And when?

========== ADDENDUM ==========

I strongly disagree with this statement:

It all hinges on this line: std::ifstream input_file(filename); where filename is a std::string.

I strong AGREE with this statement:

You get almost the same error in C# if you have static class members that depend on each other and they aren't initialised in the order you expect. In C++, if you had a static singleton and another static member that referred to it

Calling "ifstream" isn't the problem per se. Rather, somehow invoking the class that invokes ifstream before the program has initialized is the problem.

Q: Are you calling "new" on this class? If so, where. Please cut/paste that code.

Per MSDN, you should be able to set "mixed mode debugging". I have lots of different copies of MSVS :) ... but MSVS 2010/C++ doesn't happen to be one of them. Please look at this documentation:

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • Hi, I did this. The break point never gets reached. Simply having the constructor in the code causes the problem, even though it is never reached it. Commenting out the constructor, setting my ptr to NULL and doing `if(ptr != NULL) ptr->SomeFunction()` throws the same error. – Constantin Jul 05 '12 at 17:50
  • Q: Did you explicitly "enable unmanaged debugging" in your MSVS IDE? Q: Are you using MSVS 2010 Pro(or higher), or MSVS 2010 Express? Are you using C++/CLI (managed code), or unmanaged code? – paulsm4 Jul 05 '12 at 17:52
  • Hans Passant suggested that as well, however, I cannot find the option in the project property pages. I am using managed code for them Form, but it is using unmanaged c++ libraries I have written. Most of these work, this newest one does not if I use `std::ifstream` – Constantin Jul 05 '12 at 17:53
  • @Constantin - I added some new info. Please *don't* focus on "std::ifstream" ... with the possible exception that maybe you're invoking the 16-bit Unicode version of ifstream but the code expects the 8-bit ASCII version (or vice versa). But I think your time is better spent 1) getting the debugger working, and 2) finding the static object instance I'm pretty sure you're creating (creating prematurely!) IMHO... And please post some more code, it it's even remotely applicable... – paulsm4 Jul 05 '12 at 18:37
  • Paul, I got the debugger working, sadly the third party C++libraries I am using did not come with debug compiled libs. Thus my libraries which invoke the third party libraries are also compiled "Release". Paul, I think you're onto something with the 8-bit ASCII and 16-bit ASCII. Mainly because I removed ALL constructor calls from my application. I will revise my code above to show. – Constantin Jul 05 '12 at 18:41
  • Paul notice, I commented out the "new" call, the AccessViolation still exists. I can't stress enough, that this does not occur while the program is running but while loading. – Constantin Jul 05 '12 at 18:52