Solved

application crash outside Visual Studio

Posted on 2003-11-19
8
426 Views
Last Modified: 2013-11-20
hi,

i've developped an mfc application, which uses 2 external dlls (Xerces and curl) and an activeX control to access the local machine's WMI and produce a XML file with the information.
The application does it's stuff in a timer triggered loop, ie every 30 seconds or so it accesses some info via WMI.

Everything works fine when I run the app inside VS.NET (in both debug and release configs), but when i run the app outside the IDE, it crashes after the first loop (sometimes it goes for a few loops, sometimes just one).

All this in windows xp sp1.

All the memory leak detectors i've tried report no leaks.

When I JIT debug, I see that the crash happens on code that has worked on previous iterations, sometimes on the Xerces stuff, other times on my registry accessing functions (RegQueryValueEx, namely). I get a "Memory could not be read[/written] sometimes" error. I have looked in to some dynamic condition that would cause the error, but i can't get past the fact that all the iterations are exactly alike (same information retrieved over and over again) and the code works inside VS.NET (both configs).

All this happens only from the second iteration of the program onward. To my best knowledge, the registry related system calls are made as seen on the msdn sample code. xerces stuff is also very much like the samples (including cleanup stuff).

help much appreciated. thanks!

sopppas
0
Comment
Question by:sopppas
8 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9781957
>>Everything works fine when I run the app inside VS.NET

As you haven't posted any code: Check for uninitialized variables, especially pointers. The behaviour you described is typical for such small mistakes.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9785224
The difference in running application from VS and out of it is current directory. Maybe this can be a reason?
0
 

Author Comment

by:sopppas
ID: 9786114
hi,

AlexFM I've tried running the program inside the Debug|Release directory and in the project dir. No luck!

I'm gonna provide you with some code, then:

- the whole program is a systray application which, from time to time, iterates do find system info. This is done with the following loop:

void CEasyAppDlg::OnTimer (UINT TimerVal)
{
      KillTimer(timerId);

#ifdef _DEBUG
      CMemoryState oldMemState, newMemState, diffMemState;
      oldMemState.Checkpoint();
#endif
      
      CEasyApp::XMLCreate();
      

#ifdef _DEBUG
      newMemState.Checkpoint();
      if( diffMemState.Difference( oldMemState, newMemState ) )
    {
        TRACE( "Memory leaked!\n" );
            oldMemState.DumpStatistics();
    }
#endif

      timerId = SetTimer(IDT_TIMER_0, 1000, NULL); // 30 segundos
}

this function is also called when the program is first started, ie inside the OnInitDialog. As previously stated, no memory leaks are reported by CMemoryState.

- anyways, CEasyApp::XMLCreate is the core function of the program: it makes A LOT of wmi queries, a few registry ones, and uses xerces to create a XML file with the collected system info. These queries are made from within an ocx active X controller. The following are examples of how I'm doing this
 
      
      // inside XMLCREATE
      CString str;
      str = CagenteActXApp::getDomainAndName(); // the getDomainAndName function is in the ocx

      machineElem->setAttribute(X("id"), X(str)); // these are Xerces lib functions.
      ////////////////////////////


      // this function is defined in the ocx
      CString CagenteActXApp::getDomainAndName() {

      HRESULT hr;

      // Get list of objects
      CComPtr<IEnumWbemClassObject> spEnumInst;
      CComBSTR bstrQuery("SELECT * FROM Win32_ComputerSystem");

      hr = spServices->ExecQuery(CComBSTR(_T("WQL")), bstrQuery,
                  WBEM_FLAG_BIDIRECTIONAL, NULL, &spEnumInst); // some crashes occur in this line on the 2nd or 3rd iteration

      CComVariant varName, domain;
      bool bFinished = false;
      while (!bFinished)
      {
            ULONG uNumOfInstances = 0;
            CComPtr<IWbemClassObject> spInstance;
            HRESULT hrNext = spEnumInst->Next(10000, 1, &spInstance,
                  &uNumOfInstances);
            
            if (hrNext == WBEM_S_FALSE || uNumOfInstances == 0)
                  bFinished = true;
            else
            {
                  // Get properties from the object
                  hr = spInstance->Get(CComBSTR(_T("Name")), 0, &varName, 0, 0);
                  hr = spInstance->Get(CComBSTR(_T("Domain")), 0, &domain, 0, 0);
      
            }
      }

      BSTR bstr = V_BSTR(&domain);
      BSTR bstr2 = V_BSTR(&varName);
      
      CString cs(bstr);
      cs += "\\";
      CString cs2(bstr2);
      cs += cs2;
      
      VariantClear(&varName);
      VariantClear(&domain);

      return cs;  // returns something like WORKGROUP\MYCOMPUTER
      }
      /////////////////

      // again in XMLCreate;
      list<CString> propVal2;
      CagenteActXApp::getSoftwareSet(&propVal2); // this retrieves all the installed programs
      //////////////////////

      void CagenteActXApp::getSoftwareSet(std::list<CString> *res) {


      CHAR    swName[sizeof( DWORD ) * 1024] = ""; // Buffer for class name.


      HKEY hKey;
      HKEY hKeyRoot;

      hKeyRoot = HKEY_LOCAL_MACHINE;

      HRESULT retCode;

      retCode = RegOpenKeyEx (hKeyRoot,
                            "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
                            0,
                            KEY_ALL_ACCESS,
                            &hKey);

      list<char *> keys;
      HRESULT hr = 0;
      int j = 0;
      while(hr != ERROR_NO_MORE_ITEMS) {
            DWORD dwSize = sizeof( DWORD ) * 1024;
            swName[0] = '\0';
            rucucu = RegEnumKeyEx(
                                    hKey,         // handle of key to enumerate
                                    j,            // index of subkey to enumerate
                                    swName,         // address of buffer for subkey name
                                    &dwSize,         // address for size of subkey buffer
                                    NULL,         // reserved
                                    NULL,         // address of buffer for class string
                                    0,            // address for size of class buffer
                                    NULL          // address for time key last written to
                                    );
            keys.push_back(strdup(swName));
            j++;
      }

      while(!keys.empty()) {
            TCHAR skey[sizeof(DWORD)*1024];
            DWORD dwSize = sizeof( DWORD ) * 1024;
            strcpy(skey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\0");
            strcat(skey, "\\");
            strcat(skey, keys.front());
            strcat(skey, "\0");
            delete keys.front();
            keys.pop_front();
            HKEY hKey2;

            retCode = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
                            skey,
                            0,
                            KEY_ALL_ACCESS,
                            &hKey2);

            skey[0] = '\0';

            retCode = RegQueryValueEx(hKey2, "DisplayName", 0, NULL, NULL, &dwSize ); // it's been known to crash here
            retCode = RegQueryValueEx(hKey2, "DisplayName", 0, NULL, (BYTE *)&skey, &dwSize );
            if(skey[0] == '\0') {
                  dwSize = sizeof( DWORD ) * 1024;
                  retCode = RegQueryValueEx(hKey2, "Display Name", 0, NULL, NULL, &dwSize );
                  retCode = RegQueryValueEx(hKey2, "Display Name", 0, NULL, (BYTE *)&skey, &dwSize );
            }
            if(skey[0] == '\0') {
                  dwSize = sizeof( DWORD ) * 1024;
                  retCode = RegQueryValueEx(hKey2, "QuietDisplayName", 0, NULL, NULL, &dwSize );
                  retCode = RegQueryValueEx(hKey2, "QuietDisplayName", 0, NULL, (BYTE *)&skey, &dwSize );
            }

            strcat(skey, "\0");
            if(skey[0] != '\0'){
                  res->push_back(skey);
            }
            
            RegCloseKey (hKey2);

      }

      RegCloseKey (hKey);
      }
      
I think this illustrates how must of it is being done...
Thanks for the suggestions so far.
s
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 1

Expert Comment

by:bearcrsw
ID: 9805836
A couple of bits which look dubious are

     HRESULT hr = 0;
     int j = 0;
     while(hr != ERROR_NO_MORE_ITEMS) {
          DWORD dwSize = sizeof( DWORD ) * 1024;
          swName[0] = '\0';
          rucucu = RegEnumKeyEx(
                              hKey,         // handle of key to enumerate
                              j,            // index of subkey to enumerate
                              swName,         // address of buffer for subkey name
                              &dwSize,         // address for size of subkey buffer
                              NULL,         // reserved
                              NULL,         // address of buffer for class string
                              0,            // address for size of class buffer
                              NULL          // address for time key last written to
                              );
          keys.push_back(strdup(swName));
          j++;
     }

the swName is pushed onto list even if RegEnumKeyEx failed.
also hr does not ppear to be changed, as rucucu is the return value, also what about errors other than NO_MORE _ITEMS .

also on the

retCode = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
                            skey,
                            0,
                            KEY_ALL_ACCESS,
                            &hKey2);

the retVal is  not checked. Which could lead to problems with the RegQueryValueEx
0
 

Author Comment

by:sopppas
ID: 9809462
Hi everyone,

I've got it! Don't really know what was wrong, but it seems to be working now.

this code doen't work:

        CComVariant varName;
      bool bFinished = false;
      while (!bFinished)
      {
            ULONG uNumOfInstances = 0;
            CComPtr<IWbemClassObject> spInstance = 0;
            HRESULT hrNext = spEnumInst->Next(10000, 1, &spInstance,
                  &uNumOfInstances);
      
            if (hrNext == WBEM_S_FALSE || uNumOfInstances == 0) // jit debug often indicated a crash right here
                  bFinished = true;
            else
            {
 (...)

and this does:

bool bFinished = false;
      while (!bFinished)
      {
            // Get the instance
            ULONG uNumOfInstances = 0;
            CComPtr<IWbemClassObject> spInstance;
            HRESULT hrNext = spEnumInst->Next(10000, 1, &spInstance,
            &uNumOfInstances);
 
            if (hrNext == WBEM_S_FALSE)
                  bFinished = true;
            else if (hrNext == WBEM_S_NO_ERROR)
            {

I can't really tell where exactly the error is, but maybe the result is sometimes an error code other than WBEM_S_FALSE, causing the problem.
Anyway, thanks  bearcrsw for the tips (I'm gonna use them anyway), and thanks to everyone else who took the time to respond to this cry for help!

s
0
 
LVL 1

Accepted Solution

by:
Computer101 earned 0 total points
ID: 11984792
PAQed, with points refunded (500)

Computer101
E-E Admin
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
how do i create updater to My Activex application? 3 79
sum13 challenge 24 90
matchUp  challenge 6 52
pre4 challenge 19 93
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is a video describing the growing solar energy use in Utah. This is a topic that greatly interests me and so I decided to produce a video about it.

947 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now