6 Replies Latest reply on Jun 9, 2015 10:45 PM by StructInt1

    Need help w/ Unhandled Exception (PI-SDK in C++)

    StructInt1

      I have been struggling with this problem for more than a week, any *hint* of an insight would be appreciated!

       

      I am adding PI connectivity to an existing engineering application.  The App is in MS Visual C++ 2010, the main app is built using MFC, with most of the calculation done in a supporting DLL (C++, no MFC).  Of course, it is the DLL that needs to access the PI data :^>.  And unfortunately, due to the massive number of lines of code involved, re-writing the app in C# is a non-starter.

       

      I have added the new functionality, and it successfully reads from/writes to the PI server, the calculations work, BUT at the end of the calculation, I try to release the PI-SDK 'pointer' (actually a COM interface ptr) and my application throws a fatal error.

           "Unhandled Exception 0xC0000005: Access Violation writing location 0x00000014."

      To me, this error seems to indicate that something is going serioulsy wrong in tracking the references to COM pointers--but I am not very experieced in COM, so I may well be wrong about that.

       

      I need to be able to resolve this error, or we will not be able to complete and deliver the application.  My preference would be to fix whatever issue is causing this, but an acceptable fallback would be to change the way we're connecting to PI (for instance, I suspect that we could do what we need with the PI-API interface, and this issue would go away)

       

      I have previously found several example projects of PI-SDK in C++, and used them to build a 'module' within the calculation DLL to manage data transfer from/to the PI server.  It consists of a static class that acts as an interface layer between the rest of my code and the PI-SDK, and a few functions that use the interface class to retrieve/store data for the calculations:

       

      [Calculation fns.]  ==calls=>  [new interface fns.]  ==calls=>  ["PI_link" class]  ==calls=>  [PI-SDK functions]

       

      The class declaration is really simple:

       

      class PI_link

      {

      public:

          PI_link();        // needs a constructor

          ~PI_link();         // and a destructor

          short  Init ();

          bool  Connect (LPCTSTR serverID, LPCTSTR LoginCmd);

          bool  IsConnected();

          void  Release ();    // == Un-Connect()

          void  Destroy ();    // == Un-Init()

       

          static const char * TRD_PItag (int UnitNo, LPCTSTR LocID, short TrdCol, bool alloc = false);

       

          short  read_config ();

          short  check_points (LPCTSTR ptIDs[]);

          short  get_1stLast_dates (int i_instr, COleDateTime *first, COleDateTime *last);

          short  read_1hr_data (int i_instr, DATE curdate);

          short  write_datapt (LPCTSTR pointID, COleDateTime tmstamp, float value);

          short  add_Point (LPCTSTR pointID);

       

      protected:

          /* PI-SDK 'global' objects */ 

          IPISDKPtr    spPISDK;        // the PISDK //

          ServerPtr    spServer;        // the server //

       

          PIPointPtr GetPoint(LPCTSTR pointID) {

              if (!spServer) return NULL;

              return spServer->PIPoints->GetItem(pointID);

          }

      };

       

      I have traced through the code in the debugger, and it fails while executing the following function (in _my_ code):

       

      void PI_link::Destroy()

      {

          if ( IsConnected() )

              Release();        // contingency

       

          if (spPISDK != NULL) {

              //BUGBUG: this SEEMS right, but it was causing memory errors!!!

              //spPISDK->Release();

              spPISDK = NULL;     <== fails while executing this line

          }

      }

       

      The stack trace when the UE occurs shows that the access violation is occurring while the PI "session" is terminating:

       

      call_stack.png

       

      Again, I would appreciate any thoughts or insights, basically I'll try anything to get this working cleanly!

       

      Curt Carney

      Structural Integrity Assoc.

        • Re: Need help w/ Unhandled Exception (PI-SDK in C++)
          bshang

          Hi Curt,

           

          We are aware of some known issues regarding access violations within PI SDK, but first, could you provide the version of PI SDK you are using? It will help us narrow down the search. I'm wondering if the below is applicable to your issue: https://techsupport.osisoft.com/Troubleshooting/Known-Issues/63397 

          1 of 1 people found this helpful
            • Re: Need help w/ Unhandled Exception (PI-SDK in C++)
              StructInt1

              According to my PI SDK Utility, I have version 1.4.2 build 445 dated 4/22/15.

               

              Known issue 63397 sounds like it could be the same problem I'm having, except it looks like my SDK is 2 builds after the issue was fixed.  Also, the mention of RPC caught my attention.

               

              I did notice in my debugging that the error seems to occur in a worker thread.  Also, in PI-SDK-Utility I noticed a log messagethat mentioned an RPC error.  So I did a review of the log messages (the below shows 3 sessions w/ my program, and one PISDKUtility session):

               

              Time                 ID      Severity       Message

              6/09 13:28:02,       2, Error,           Failed to retrieve the list of capabilities from pibufss.  [-10727] PINET: RPC is Non-Existent., PISDKUtility, 10, PISDK, , 6004, , , STRUCTINT.AD\ccarney, , , ,

              6/09 13:28:01, 7039, Information, Connection accepted:  Process name:  PISDKUtility.exe(6004) ID: 8, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

               

              6/09 13:26:31, 7079, Information, Disconnected ID: 7 ; Process name: CFPro3.exe(2272):remote ; User:  ; OS User:  ; IP: 192.168.15.50 ; AppID:  ; AppName: , pinetmgr, 10, Connection Information, , 2204, , , SYSTEM, , , ,

              6/09 13:26:31, 7093, Information, Deleting connection:  CFPro3.exe(2272):remote, Routing ID closed by session., ID: 7  192.168.15.50:5450, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

              6/09 13:25:49,       4, Information, Successfully connected to server FP03-HMJGDD1 as piadmins | piusers | PIWorld, CFPro3, 10, PISDK, , 2272, , , STRUCTINT.AD\ccarney, , , ,

              6/09 13:25:48, 7039, Information, Connection accepted:  Process name:  CFPro3.exe(2272) ID: 6, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

               

              6/09 13:00:47, 7079, Information, Disconnected ID: 4 ; Process name: CFPro3.exe ; User:  ; OS User:  ; IP:   ; AppID:  ; AppName: , pinetmgr, 10, Connection Information, , 2204, , , SYSTEM, , , ,

              6/09 13:00:47, 7121, Information, Deleting connection:  CFPro3.exe(6104), Asynch read failed. [109] The pipe has been ended., ID: 4   :0, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

              6/09 12:59:55, 7079, Information, Disconnected ID: 5 ; Process name: CFPro3.exe(6104):remote ; User:  ; OS User:  ; IP: 192.168.15.50 ; AppID:  ; AppName: , pinetmgr, 10, Connection Information, , 2204, , , SYSTEM, , , ,

              6/09 12:59:55, 7093, Information, Deleting connection:  CFPro3.exe(6104):remote, Routing ID closed by session., ID: 5  192.168.15.50:5450, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

              6/09 12:59:30,       4, Information, Successfully connected to server FP03-HMJGDD1 as piadmins | piusers | PIWorld, CFPro3, 10, PISDK, , 6104, , , STRUCTINT.AD\ccarney, , , ,

              6/09 12:59:29, 7039, Information, Connection accepted:  Process name:  CFPro3.exe(6104) ID: 4, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

               

              6/09 12:51:21, 7079, Information, Disconnected ID: 2 ; Process name: CFPro3.exe ; User:  ; OS User:  ; IP:   ; AppID:  ; AppName: , pinetmgr, 10, Connection Information, , 2204, , , SYSTEM, , , ,

              6/09 12:51:21, 7117, Information, Deleting connection:  CFPro3.exe(6080), Subsystem Healthcheck failed. [-10722] PINET: Timeout on PI RPC or System Call. Connection not responding., ID: 2   :0, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

              6/09 11:18:32, 7079, Information, Disconnected ID: 3 ; Process name: CFPro3.exe(6080):remote ; User:  ; OS User:  ; IP: 192.168.15.50 ; AppID:  ; AppName: , pinetmgr, 10, Connection Information, , 2204, , , SYSTEM, , , ,

              6/09 11:18:32, 7093, Information, Deleting connection:  CFPro3.exe(6080):remote, Routing ID closed by session., ID: 3  192.168.15.50:5450, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

              6/09 11:18:08,       4, Information, Successfully connected to server FP03-HMJGDD1 as piadmins | piusers | PIWorld, CFPro3, 10, PISDK, , 6080, , , STRUCTINT.AD\ccarney, , , ,

              6/09 11:18:07, 7039, Information, Connection accepted:  Process name:  CFPro3.exe(6080) ID: 2, pinetmgr, 10, , , 2204, , , SYSTEM, , , ,

            • Re: Need help w/ Unhandled Exception (PI-SDK in C++)
              dng

              Hi Curt,

               

              Have you tried initializing IPISDKPtr as follow?

               

              IPISDKPtr pPISDK(__uuidof(PISDK));
              

               

              Taken from the PI SDK help file:

              This creates the main PISDK "app" object and returns a pointer to the PISDK interface. The IPISDKPtr data type is a "smart pointer" created by the wrapper classes based on _com_ptr_t.

               

              The code here calls the IPISDKPtr constructor passing the CLSID of the object (__uuidof(PISDK)). This allows the underlying code to create the object based on the CLSID and obtain a pointer to the interface IPISDK. When the smart pointer (pPISDK) goes out of scope, the interface is released automatically. True to COM, when the last reference is gone the object is destructed. Using smart pointers avoids calls to CoCreateInstance, QueryInterface, AddRef, and Release. For details on the various constructors and methods of the smart pointer classes see the Microsoft documentation for _com_ptr_t.

               

              The following discussion might also be of interest: C++ and PI - PI SDK - UpdateValues

               

              In addition, what happens when you try to release spPISDK (the line was commented out)?

              spPISDK->Release
              
              1 of 1 people found this helpful
                • Re: Need help w/ Unhandled Exception (PI-SDK in C++)
                  StructInt1

                  Good thoughts.

                   

                  My PI_Link::Init() function includes the following lines:

                       if (spPISDK == NULL) {

                            spPISDK.CreateInstance(__uuidof(PISDK));

                       }

                  I did it this way because at least some of our customers will not have PI systems, thus I don't want to try to connect immediately on startup (and fail).  Instead I connect the first time they try to do something that requires PI access.  I _think_ this is equivalent, but again my COM experience is very little, so maybe the difference is significant in some way I don't know about?  Maybe in that the spPISDK pointer is initally created with a NULL value, and then given a real value later by the CreateInstance() call?

                   

                  Regarding the call to Release(), I don't remember exactly, what I recall was that the Release() call worked, but then the "spPISDK = NULL;" statement caused an exception (because the _com_ptr_t code tried to Release it again!).

                   

                  Thanks for your contribution!  Still working on it... see also the post by Barry & my reply.

                   

                  Curt C.

                    • Re: Need help w/ Unhandled Exception (PI-SDK in C++)
                      bshang

                      Hi Curtis,

                       

                      I'm not a COM expert but I'm wondering if it's necessary to set the COM "smart pointer" IPISDKPtr to null. This object wraps around the actual IPISDK interface pointer, so it seems we should be checking if the underlying interface pointer is null. We can do so via spPISDK.GetInterfacePtr() and check if the returned pointer == null (i.e. replacing spPISDK == NULL). _com_ptr_t::GetInterfacePtr

                       

                      Technically, with _com_ptr_t, it is not necessary to explicitly call Release(). When IPISDKPtr goes out of scope, the reference count to the underlying IPISDK interface should be decremented (by one) automatically. Maybe some community members can chime in on these COM details.

                  • Re: Need help w/ Unhandled Exception (PI-SDK in C++)
                    StructInt1

                    OK gang, I think I found my mistake... and it proves an adage that I like to say, that if you can't find a mistake in your code, show it to some other programmers... and the more emarassing it is, the sooner they will find your error.

                     

                    Following up on bot of your comments, especially after noticing that the PI-SDK message log was showing 2 disconnections for each connection, I did a trace throu ALL of the shutdown code, and I discovered that the calculation routine was (indirectly) calling ::CoUninitialize() before it was returning to the main program... but PI_link::Destroy() was not called until _AFTER_ the calculation had returned.

                     

                    So I moved the destruction code back up before the ::CoUninitialize() call, and it worked no-errors 3 times in a row!

                     

                    Summary of the summary: if you close down COM support before you release all your COM objects, you will generate Exceptions when the shutdown code eventually tries to release them!

                     

                    Thanks to Barry and Daphne for getting involved... I have been working on this for a week, so I can honeslty say without your promting, I would not have gotten here today!

                     

                    Curt C.