2 Replies Latest reply on Sep 13, 2010 4:37 PM by dreed

    ADL 64bit unhandled exception

    dreed
      ADL_Display_Modes_Get creating unhandled exception

      Hello,

       

      I am trying to call ADL_Display_Modes_Get in a 64 C++ application and it generates an unhandled exception, but works fine when switched to 32 bit. This is a simple lightweight, non threaded test application. Other functions work fine in 64 bit (ADL_Display_DisplayInfo_Get). Is this a problem of the atiadl dll(s)?

       

      Background:

      64 bit Windows 7 Enterprise

      FirePro V3700 (tried with latest and second latest drivers with uninstall/reinstall)

      Visual Studios 2008

       

      I am calling LoadLibrary("atiadlxx.dll") which pulls it from the system 32 (causing the unhandled exception). Also, in an attempt to force it to load from syswow64 via

      LoadLibraryEx("C:\\Windows\\SysWOW64\\atiadlxy.dll", NULL, LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_WITH_ALTERED_SEARCH_PATH);

      causes windows to generate an errorcode 193: ERROR_BAD_EXE_FORMAT(not a valid Win32 application)

       

      The application I am writing needs to be in 64 bit. Since I am just looking for the display parameters of connected displays(color depth, refresh rate, etc) is there another way to go about retrieving this information or any workarounds? I can attach the test application code if that would help.

       

      Thank You!

        • ADL 64bit unhandled exception
          Byron

          On a 32-bit OS, System32 contains 1 DLL: a 32-bit DLL called atiadlXX.dll
          On a 64-bit OS, System32 contains 1 DLL: a 64-bit DLL called atiadlXX.dll, and SysWOW64 contains a 32-bit DLL called atiadlXY.dll.

          The above are Microsoft conventions. With the above pattern, code written to load a DLL from System32 can be compiled for 32-bit (loads 32-bit DLL from System32 on 32-bit OS, or loads 32-bit DLL from SysWOW64 on a 64-bit OS because Microsoft "redirects" the 32-bit APIs to this other directory), and the same code compiled for 64-bit need not change since a 64-bit process on a 64-bit OS loads 64-bit DLLs located in System32.

          You indicate in first sentence "64 C++ application" but later on you indicate trying to load from System32 (which should be the appropriate 64-bit DLL) and a manual attempt to load from SysWOW64 (the inappropriate 32-bit DLL) and in both cases fail (but for different reasons). The failure from System32 is not expected, however, the failure to load a 32-bit DLL into a 64-bit process is an expected failure.

           

          Some questions:
          1. Did you supply a "Memory Allocation Call Back Routine"? Many of the ADL calls require allocation of new buffers whose size is not known prior to the caller making the API call, so the ADL API then uses the call back to request the caller to allocation memory of size "X", ADL fills in the buffer, and returns the buffer via the original API request - the caller is expected to free the buffer thereafter. Sometimes ADL allocates multiple memory buffers before returning, and the returned structure will be documented as how to free all of the parts.

          2. Did you request a deep enough stack? ADL in some cases allocates temporary space on the stack, and if the caller's program has a small stack, then ADL may fail some API.

          3. Can you supply a text based stack dump to identify which internal API caused the exception?

          4. Can you provide sample code to reproduce the issue?

            • ADL 64bit unhandled exception
              dreed

               

              Thank you for the reply. 

              The 64-bit DLL existing in the System32 folder was a very interesting and insightful piece of information, albeit a bit counter intuitive. 

              I have created an image of the error shown with the stack trace in the link below.

              http://imgur.com/PZYET.jpg

              In response to your questions:

              1. Yes I have created a memory allocation routine found in the attached code. I removed the memory deallocation section just to be sure that wasn't the issue.

              2. To test this I reserved 1024 bytes for both the heap and the stack, neither resulted in any change.

              3. Included in the image, the last line in Visual Studios call stack was: atiadlxx.dll!000000018001f098(). I don't know if Visual Studios call stack is sufficient enough, let me know if I can provide anything further. 

              4. I have attached my entire (small) test file. 

               



              #include <stdio.h> #include "adl_sdk.h" #include <windows.h> // Memory allocation function void* __stdcall ADL_Main_Memory_Alloc ( int iSize ) { void* lpBuffer = malloc ( iSize ); return lpBuffer; } // end of -- void* __stdcall ADL_Main_Memory_Alloc ( int iSize ) int main(int _argc, char* _argv[]) { // Definitions of the used function pointers. Add more if you use other ADL APIs typedef int ( *ADL_MAIN_CONTROL_CREATE )(ADL_MAIN_MALLOC_CALLBACK, int ); typedef int ( *ADL_MAIN_CONTROL_DESTROY )(); typedef int ( *ADL_DISPLAY_MODES_GET ) (int iAdapterIndex, int iDisplayIndex, int* lpNumModes, ADLMode** lppModes); ADL_DISPLAY_MODES_GET ADL_Display_Modes_Get; ADL_MAIN_CONTROL_CREATE ADL_Main_Control_Create; ADL_MAIN_CONTROL_DESTROY ADL_Main_Control_Destroy; HINSTANCE amdDll_ = NULL; LPADLMode adlMode_ = NULL; amdDll_ = LoadLibrary("atiadlxx.dll"); if (amdDll_ == NULL) { // A 32 bit calling application on 64 bit OS will fail to LoadLIbrary. // Try to load the 32 bit library (atiadlxy.dll) instead //amdDll_ = LoadLibraryEx("C:\\Windows\\SysWOW64\\atiadlxy.dll", NULL, LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_WITH_ALTERED_SEARCH_PATH); amdDll_ = LoadLibraryEx("atiadlxy.dll", NULL, LOAD_IGNORE_CODE_AUTHZ_LEVEL); } // end of -- if (amdDll_ == NULL) if (amdDll_ == NULL) { char errorBuffer[MAX_PATH] = {0}; FormatMessage ((FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS), NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) errorBuffer, MAX_PATH, NULL); printf("ADL library not found: %i:%s\n", GetLastError(), errorBuffer); getchar(); } // end of -- if (amdDll_ == NULL) else { ADL_Display_Modes_Get = (ADL_DISPLAY_MODES_GET) GetProcAddress(amdDll_,"ADL_Display_Modes_Get"); if (ADL_Display_Modes_Get == NULL) { printf("ADL_Display_Modes_Get API is missing!\n"); } // end of -- if (ADL_Display_Modes_Get == NULL) ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE) GetProcAddress(amdDll_,"ADL_Main_Control_Create"); if (ADL_Main_Control_Create == NULL) { printf("ADL_Main_Control_Create API is missing!\n"); } // end of -- if (ADL_Main_Control_Create == NULL) ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY) GetProcAddress(amdDll_,"ADL_Main_Control_Destroy"); if (ADL_Main_Control_Destroy == NULL) { printf("ADL_Main_Control_Destroy API is missing!\n"); } // end of -- if (ADL_Main_Control_Destroy == NULL) // Initialize ADL. The second parameter is 1, which means: // retrieve adapter information only for adapters that are physically present and enabled in the system if ( ADL_OK != ADL_Main_Control_Create (ADL_Main_Memory_Alloc, 1) ) { printf("ADL Initialization Error!\n"); } // end of -- if ( ADL_OK != ADL_Main_Control_Create (ADL_Main_Memory_Alloc, 1) ) else { int iNumModes_ = 0; printf("about get call ADL_Display_Modes_Get!\n"); int error_ = ADL_Display_Modes_Get (-1, -1, &iNumModes_, &adlMode_); if (error_ == ADL_OK) { printf("ADL_Display_Modes_Get worked!\n"); } // end of -- if (error_ == ADL_OK) } // end of -- else } // end of -- else // clean up if (ADL_Main_Control_Destroy) { ADL_Main_Control_Destroy(); } // end of -- if (ADL_Main_Control_Destroy) if (amdDll_) { FreeLibrary(amdDll_); } // end of -- if (amdDll_) getchar(); return 0; } // end of -- int main(int _argc, char* _argv[])