Thread: Random crashes? huh?

  1. #16
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I think I found the cause of the LoadLibrary() problems. If I comment out this line in DllMain(), it never fails to load:
    Code:
    BOOL APIENTRY
    DllMain( HANDLE /*hModule*/,
    		 DWORD  ul_reason_for_call,
    		 LPVOID /*lpReserved*/
    		)
    {
    	TRACE( "*** DllMain() ***" );
    
        switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    			TRACE( "DLL_PROCESS_ATTACH" );
    //			CUExit::ReadCfgFile();
    			break;
    		case DLL_THREAD_ATTACH:
    			TRACE( "DLL_THREAD_ATTACH" );
    			break;
    		case DLL_THREAD_DETACH:
    			TRACE( "DLL_THREAD_DETACH" );
    			break;
    		case DLL_PROCESS_DETACH:
    			TRACE( "DLL_PROCESS_DETACH" );
    			break;
        }
    
    	return TRUE;
    }
    
    bool
    CUExit::ReadCfgFile()
    {
    	TRACE( "*** CUExit::ReadCfgFile() ***" );
    	Tifstream fin( "UExit.cfg" );
    
    	if ( !fin )
    	{
    		TRACE( "readCfgFile():  Failed to open file UExit.cfg!" );
    		return false;
    	}
    
    	if ( !std::getline( fin, m_ScriptToCall ) )
    	{
    		TRACE( "readCfgFile():  getline() failed!" );
    		return false;
    	}
    
    	TRACE( _T("readCfgFile():  m_ScriptToCall = '") + m_ScriptToCall + _T("'") );
    	return true;
    }
    EDIT: Oh crap, I spoke too soon...
    Last edited by cpjust; 07-08-2008 at 01:59 PM.

  2. #17
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Are you allowed to do that kind of work in DLLMain()? I would expect so, but from this article I think you should just do the most basic initialization of variables:

    http://msdn.microsoft.akadns.net/en-.../ms682583.aspx

    Perhaps you should call that function in your DLL from your EXE.

  3. #18
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You shouldn't take any locks in DllMain, and the streams often do internal locking, so it's risky.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #19
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by CornedBee View Post
    You shouldn't take any locks in DllMain, and the streams often do internal locking, so it's risky.
    OK, I moved it into a different place. Now DllMain() does nothing but return TRUE, but when I loop through several dozen LoadLibrary/FreeLibrary calls I get eventually get "Not enough storage is available to process this command." I put a 50ms sleep between LoadLibrary/FreeLibrary calls in case it was a timing issue, but that didn't help.

    I also tried building new projects in VC++ 6.0 (using the same source files) and it's giving the same results.

  5. #20
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Do you have any global or static objects in the DLL?

  6. #21
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by MacGyver View Post
    Do you have any global or static objects in the DLL?
    Not anymore.
    Although I'm still getting bad_alloc's and the "Not enough storage is available to process this command." LoadLibrary() errors after loading/unloading the DLL about 20-30 times.

    These are the header files included in the DllMain file; I don't know if they have any objects in them that would cause any problems?
    Code:
    #include <windows.h>
    #include <tchar.h>
    #include <conio.h>	// DEBUG ONLY
    #include <fstream>
    #include <sstream>
    #include <cstdio>		// For _spawnv() & _wspawnv().
    #include <process.h>	// For _P_NOWAIT.
    Last edited by cpjust; 07-08-2008 at 03:13 PM.

  7. #22
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    OK, I've stripped this down to the bare bones and LoadLibrary() still fails after 20-30 calls:

    stdafx.h:
    Code:
    #if !defined(AFX_STDAFX_H__7B54890C_3655_4A2C_BA76_444CC4D20F7E__INCLUDED_)
    #define AFX_STDAFX_H__7B54890C_3655_4A2C_BA76_444CC4D20F7E__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    // Insert your headers here
    #define WIN32_LEAN_AND_MEAN	// Exclude rarely-used stuff from Windows headers
    
    #include <windows.h>
    #include <tchar.h>
    
    #endif // !defined(AFX_STDAFX_H__7B54890C_3655_4A2C_BA76_444CC4D20F7E__INCLUDED_)
    UExit.h:
    Code:
    #ifndef UEXIT_H_INCLUDED_JULY_2_2008
    #define UEXIT_H_INCLUDED_JULY_2_2008
    
    #ifdef _XDLL
    #  define UEXIT_API __declspec(dllexport)
    #else
    #  define UEXIT_API __declspec(dllimport)
    #endif
    
    #endif	// UEXIT_H_INCLUDED_JULY_2_2008
    UExit.cpp:
    Code:
    #include "stdafx.h"
    #include "UExit.h"
    
    BOOL APIENTRY
    DllMain( HANDLE /*hModule*/,
    	 DWORD  ul_reason_for_call,
    	 LPVOID /*lpReserved*/
    	)
    {
    	switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    			break;
    		case DLL_THREAD_ATTACH:
    			break;
    		case DLL_THREAD_DETACH:
    			break;
    		case DLL_PROCESS_DETACH:
    			break;
    	}
    
    	return TRUE;
    }
    TestHarness.cpp:
    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    
    HMODULE
    LoadDLL()
    {
    	HMODULE hDLL = LoadLibrary( _T("UExit.dll") );
    
    	if ( hDLL == NULL )
    	{
    		cout << "Error loading DLL!" << endl;
    		exit( 1 );
    	}
    	else
    	{
    		cout << "DLL Loaded successfully." << endl;
    	}
    
    	return hDLL;
    }
    
    void
    UnloadDLL( HMODULE&  hDLL )
    {
    	if ( hDLL == NULL )
    	{
    		cout << "The DLL isn't loaded!" << endl;
    	}
    	else
    	{
    		if ( FreeLibrary( hDLL ) == FALSE )
    		{
    			cout << "Error unloading DLL!" << endl;
    		}
    		else
    		{
    			cout << "DLL unloaded successfully." << endl;
    			hDLL = NULL;
    		}
    	}
    }
    
    int main()
    {
    	HMODULE hDLL = NULL;
    
    	for ( int i = 0; i < 1000; ++i )
    	{
    		cout << "*** " << i << endl;
    		Sleep( 50 );
    		hDLL = LoadDLL();
    		Sleep( 50 );
    		UnloadDLL( hDLL );
    	}
    
    	return 0;
    }
    How can THIS possibly be failing???

  8. #23
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Windows is broken? Have you googled for similar things?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #24
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Moral of the story: prefer static linking.

  10. #25
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Minimal example (sans the no-op switch in DllMain) runs fine on my computer - currently at 400.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #26
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by CornedBee View Post
    Minimal example (sans the no-op switch in DllMain) runs fine on my computer - currently at 400.
    Which compiler?
    Can you post the Compile & Link options? Maybe I've got something messed up there?
    Here are my settings for the UExit.dll:
    Code:
    /O2 /GL /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "UNICODE" /D "_UNICODE" /D "_XDLL" /D "_WINDLL"
    /FD /EHsc /MD /Fo"Release\\" /Fd"Release\vc80.pdb" /W4 /WX /nologo /c /Zi /TP /errorReport:prompt
    
    
    /OUT:"D:\Programming\C++\UExit\x86-vc8\Release\UExit.dll" /INCREMENTAL:NO /NOLOGO /DLL /MANIFEST /MANIFESTFILE:"Release\UExit.dll.intermediate.manifest"
    /DEBUG /PDB:"d:\Programming\C++\UExit\x86-vc8\Release\UExit.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT
    kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
    and the Test Harness:
    Code:
    /O2 /GL /I "..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "UNICODE" /D "_UNICODE" /D "_CRT_SECURE_NO_WARNINGS"
    /FD /EHsc /MD /Fo"Release\\" /Fd"Release\vc80.pdb" /W4 /WX /nologo /c /Zi /TP /errorReport:prompt
    
    
    /OUT:"D:\Programming\C++\UExit\x86-vc8\Release\TestHarness.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"Release\TestHarness.exe.intermediate.manifest"
    /DEBUG /PDB:"d:\Programming\C++\UExit\x86-vc8\Release\TestHarness.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT
    kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

  12. #27
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Sounds a bit like this: http://forums.msdn.microsoft.com/en/...-1398db52a6ba/

    This thread's even better: http://www.gamedev.net/community/for...opic_id=440135

    But I don't know if that answers your question or not . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #28
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    VC++.Net 2003, default empty Win32 DLL & Console app, debug build.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #29
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by CornedBee View Post
    VC++.Net 2003, default empty Win32 DLL & Console app, debug build.
    Sonofa..........! I just created a brand new DLL and Console project in VC++ 2008 express and compiled those files, and it ran with no problems whatsoever (although I used a newer compiler than at work and I'm running Vista instead of XP).

    The only differences in compiler options are the addition of these switches: /Oi /Gy
    and these Linker options: /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DYNAMICBASE /NXCOMPAT

    EDIT: and then I removed those differences too and it still worked. I think this might be a good excuse for me to work at home from now on.
    Last edited by cpjust; 07-09-2008 at 08:57 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. random to int?
    By psyadam in forum C# Programming
    Replies: 7
    Last Post: 07-22-2008, 08:09 PM
  2. Lesson #3 - Math
    By oval in forum C# Programming
    Replies: 2
    Last Post: 04-27-2006, 08:16 AM
  3. Another brain block... Random Numbers
    By DanFraser in forum C# Programming
    Replies: 2
    Last Post: 01-23-2005, 05:51 PM
  4. How do I restart a random number sequence.
    By jeffski in forum C Programming
    Replies: 6
    Last Post: 05-29-2003, 02:40 PM
  5. Best way to generate a random double?
    By The V. in forum C Programming
    Replies: 3
    Last Post: 10-16-2001, 04:11 PM