Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Access violation when throwing exception in 64 bit DLL


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 9 - Last Post: Jan 31, 2018 2:05 AM Last Post By: Ivan Johansen
Ivan Johansen

Posts: 27
Registered: 3/17/00
Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 12:15 AM
I am evaluating C++ Builder 10.2. I have created a simple DLL with the following code:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  if(reason==1)
    try
    {
      throw Exception("");
    }
    catch(Exception &E)
    {
      MessageBox(NULL, L"Testing", L"Test", MB_OK);
    }
  return 1;
}


When the DLL is loaded it should throw an exception that is immediately caught and show a message.

If I create a small C++ program that loads the DLL with LoadLibrary() it works fine. However if I try to load it from Python I get an exception in the debugger that says:
Project python.exe raised exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.

I am using the following code to load the DLL from Python, which basically does the same as calling LoadLibrary from C++:
from ctypes import *
cdll.LoadLibrary(r"C:\Users\Ivan Johansen\Documents\Embarcadero\Studio\Projects\Win64\Debug\Project23.dll")


This only happens when I compile as 64 bit. When I compile as 32 bit there is no problem. Also I cannot reproduce it with C++ Builder XE6.
The access violation happens every time a Delphi exception is thrown anywhere in the DLL, but it doesn't seem to happen with C++ exceptions.

I am unsure if this is a bug in the compiler or I need to do something to prevent this. I also don't understand why this only happens when I load the DLL from Python and not from a C++ program.

Can anyone help me reproduce this and confirm that it is not only a problem on my computer? And can anyone help me track down the cause of this problem?

I have a vague idea that it might have something to do with Data Execution Prevention, but I don't know how to debug that.

Ivan Johansen
Andy Walker

Posts: 72
Registered: 1/20/01
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 2:29 AM   in response to: Ivan Johansen in response to: Ivan Johansen
Ivan Johansen wrote:
I am evaluating C++ Builder 10.2. I have created a simple DLL with the following code:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  if(reason==1)
    try
    {
      throw Exception("");
    }
    catch(Exception &E)
    {
      MessageBox(NULL, L"Testing", L"Test", MB_OK);
    }
  return 1;
}


When the DLL is loaded it should throw an exception that is immediately caught and show a message.

Is this a 64-bit DLL or a 32-bit DLL?

If I create a small C++ program that loads the DLL with LoadLibrary() it works fine. However if I try to load it from Python I get an exception in the debugger that says:
Project python.exe raised exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.

Are you creating a 64-bit .exe or a 32-bit .exe?


I am using the following code to load the DLL from Python, which basically does the same as calling LoadLibrary from C++:
from ctypes import *
cdll.LoadLibrary(r"C:\Users\Ivan Johansen\Documents\Embarcadero\Studio\Projects\Win64\Debug\Project23.dll")


Is this 64-bit Python or a 32-bit Python

This only happens when I compile as 64 bit. When I compile as 32 bit there is no problem. Also I cannot reproduce it with C++ Builder XE6.
The access violation happens every time a Delphi exception is thrown anywhere in the DLL, but it doesn't seem to happen with C++ exceptions.

You can see where I'm going with my questions above...are you mixing 32-bit and 64-bit? A DLL is in-process and so you can't mix bitness.

I am unsure if this is a bug in the compiler or I need to do something to prevent this. I also don't understand why this only happens when I load the DLL from Python and not from a C++ program.

Can anyone help me reproduce this and confirm that it is not only a problem on my computer? And can anyone help me track down the cause of this problem?

I have a vague idea that it might have something to do with Data Execution Prevention, but I don't know how to debug that.

I have had this issue before and the only way I proved it was to disable DEP temporarily. Just google "Switch off DEP" and find the steps for your OS, https://www.google.co.uk/search?q=switch+off+DEP&sourceid=ie7&rls=com.microsoft:en-GB:IE-Address&ie=&oe=&gfe_rd=cr&dcr=0&ei=Y0dwWuvZIe6LtgetmIGQBA&gws_rd=ssl

If you don't progress just reply here and confirm what OS and whether you are building .exe and .dll as 32-bit or 64-bit and I'll see if I can confirm whether it works for me.

Andy
Ivan Johansen

Posts: 27
Registered: 3/17/00
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 3:12 AM   in response to: Andy Walker in response to: Andy Walker
Andy Walker wrote:
Is this a 64-bit DLL or a 32-bit DLL?

It is a 64 bit DLL.

Are you creating a 64-bit .exe or a 32-bit .exe?

A 64 bit .exe.

Is this 64-bit Python or a 32-bit Python

64 bit Python.

You can see where I'm going with my questions above...are you mixing 32-bit and 64-bit? A DLL is in-process and so you can't mix bitness.

Yes, but it is not even possible to load a 64 bit DLL from 32 bit Python.

I have had this issue before and the only way I proved it was to disable DEP temporarily. Just google "Switch off DEP" and find the steps for your OS, https://www.google.co.uk/search?q=switch+off+DEP&sourceid=ie7&rls=com.microsoft:en-GB:IE-Address&ie=&oe=&gfe_rd=cr&dcr=0&ei=Y0dwWuvZIe6LtgetmIGQBA&gws_rd=ssl

DEP is already set to "Turn on DEP for essential Windows programs and services only". However I am a little unsure if this only affects 32-bit programs.

If you don't progress just reply here and confirm what OS and whether you are building .exe and .dll as 32-bit or 64-bit and I'll see if I can confirm whether it works for me.

I am using Windows 10 64-bit.
Everything regarding the problem is 64 bit on C++ Builder 10.2 trial version.
Until now I have been using a 32 bit DLL with 32 bit Python, which works perfectly. But now I want to make it work with 64 bit, but it crashes every time an exception is thrown.

When the exception from the code is caught by the debugger and I click Break in the dialog, the CPU view shows that execution has stopped at this address and code:
00007FFBC3723FB8 488B8C24C0000000 mov rcx,[rsp+$00c0]

If the DLL is loaded from a C++ program, I can step over this line. However if the DLL is loaded from Python, I get an access violation when I try to step over the line. It is the exactly same code in both cases. That is why I thought it might have something to do with DEP.

But I have now tried to call VirtualQuery() to get information about the address (0x00007FFBC3723FB8), and it says that the page is executable in both the working and non working case.
So it might not have anything to with DEP. I just cannot figure out what is going on.

Ivan Johansen
Andy Walker

Posts: 72
Registered: 1/20/01
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 3:25 PM   in response to: Ivan Johansen in response to: Ivan Johansen
Hi Ivan

I'm not sure how much further help I can be but I have been looking at this today and couldn't really reproduce the exact error you are seeing, but I did see some issues.

For me, 64 bit DLL with 64 bit Python and the code you supplied causes OSError: [WinError 1114] A dynamic link library (DLL) initialisation routine failed, and the DLL fails to load.

Remove the try...catch and the error disappears and the DLL loads. Change the catch(Exception &e) to catch(...) and the DLL loads.

It seems to be the act of throwing and catching "Exception" that causes issues.

I created a separate function that throws an Exception and catches it using catch(Exception &e) and calling that function raises a OSError: exception: access violation reading 0x00000000961B14C0

A duplicate function that throws an Exception and catches it using catch(...) works correctly.

A function that throws an int and catches with catch (int x) works correctly.

Catching with const reference doesn't seem to affect the functionality "catch(const Exception &e)"


#include <vcl.h>
#include <windows.h>
#include <stdio.h>
 
#pragma hdrstop
#pragma argsused
extern "C" __declspec(dllexport) void function(void);
extern "C" __declspec(dllexport) void exceptionfunction1(void);
extern "C" __declspec(dllexport) void exceptionfunction2(void);
extern "C" __declspec(dllexport) void intfunction(void);
 
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}
 
 void function(void) {
  puts("Hello");
}
 
void exceptionfunction1(void) {
	try
	{
	  throw (Exception("exception"));
	}
	catch(...)
	{
	  puts("An Exception 1");
	}
}
void exceptionfunction2(void) {
	try
	{
	  throw (Exception("exception"));
	}
	catch(Exception&)
	{
	  puts("An Exception 2");
	}
}
void intfunction(void) {
	try
	{
	  throw (2);
	}
	catch(int x)
	{
	  puts("An int Exception");
	}
}


I'm using Windows 8.1, Python 3.6, C++ Builder Tokyo 10.2.2

Are you linking with Dynamic RTL and runtime packages? If I link statically and without runtime packages then Python crashes as soon as "Exception" is thrown but throwing and catching "int" works fine.

I'm intrigued now so I will carry on investigating but please post here if you work out what the issue is and we can raise an issue in Quality Portal.

Andy

Edited by: Andy Walker on Jan 30, 2018 3:41 PM
Ivan Johansen

Posts: 27
Registered: 3/17/00
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 31, 2018 2:05 AM   in response to: Andy Walker in response to: Andy Walker
Andy Walker wrote:
I'm not sure how much further help I can be but I have been looking at this today and couldn't really reproduce the exact error you are seeing, but I did see some issues.

That is strange. I can reproduce it every time.

For me, 64 bit DLL with 64 bit Python and the code you supplied causes OSError: [WinError 1114] A dynamic link library (DLL) initialisation routine failed, and the DLL fails to load.
Remove the try...catch and the error disappears and the DLL loads. Change the catch(Exception &e) to catch(...) and the DLL loads.

It doesn't make any difference for me when I replace catch(Exception &e) with catch(...). I get an access violation on both cases.

It seems to be the act of throwing and catching "Exception" that causes issues.

Yes, that was my conclusion as well.

I created a separate function that throws an Exception and catches it using catch(Exception &e) and calling that function raises a OSError: exception: access violation reading 0x00000000961B14C0

I never see OSError, but instead exception class $C0000005.

A duplicate function that throws an Exception and catches it using catch(...) works correctly.

I copied your code and tried it, and I get the exact same access violation when calling the function that uses catch(...)

A function that throws an int and catches with catch (int x) works correctly.

Yes, it looks like the access violation only happens with Delphi exceptions. Throwing std::exception also works correctly.

Are you linking with Dynamic RTL and runtime packages? If I link statically and without runtime packages then Python crashes as soon as "Exception" is thrown but throwing and catching "int" works fine.

I am linking with static RTL and without runtime packages. But changing it doesn't seem to make any difference for me.

I'm intrigued now so I will carry on investigating but please post here if you work out what the issue is and we can raise an issue in Quality Portal.

Thanks a lot for the help. It is much appreciated.
I will keep you updated if I find anything.

Using EditBin to manually set a flag on the compiled .dll to tell windows that it is compatible with Windows DEP also makes no difference so I think you can probably rule that out too?

Yes, I am not sure it has anything to do with DEP. I am just having difficulties explaining why it makes a difference which program loads the DLL. I have also been checking all CPU/FPU configuration registers to see if there was a difference, but I could not find any.

Ivan Johansen

Andy Walker

Posts: 72
Registered: 1/20/01
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 4:43 PM   in response to: Ivan Johansen in response to: Ivan Johansen
Ivan Johansen wrote:
DEP is already set to "Turn on DEP for essential Windows programs and services only". However I am a little unsure if this only affects 32-bit programs.

Using EditBin to manually set a flag on the compiled .dll to tell windows that it is compatible with Windows DEP also makes no difference so I think you can probably rule that out too?

https://msdn.microsoft.com/en-us/library/d25ddyfc.aspx

C:\Program Files (x86)\Microsoft Visual Studio 14.0>editbin.exe /TSAWARE /NXCOMPAT /DYNAMICBASE C:\Users\Andy\Documents\Embarcadero\Studio\Projects\Win64\Debug\xxx.dll


I also went down the route of wondering if the linker is not setting the flag to ensure safe exception handling but that is only 32-bit.

Regards,

Andy
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 9:35 AM   in response to: Ivan Johansen in response to: Ivan Johansen
Ivan Johansen wrote:

I have created a simple DLL with the following code:

You should be catching the Exception by const reference.

Also, it is NOT safe to call MessageBox() (or any other UI function) in
DllEntryPoint():

Dynamic-Link Library Best Practices
https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971.aspx

You should never perform the following tasks from within DllMain:

...

- Call functions in User32.dll or Gdi32.dll. Some functions load
another DLL, which may not be initialized.

...

If you need to display an error message, you will have to use something
like OutputDebugString(), or write the error message to a file (as most
kernel32.dll functions are safe to call in DllEntryPoint()), etc.

--
Remy Lebeau (TeamB)
Ivan Johansen

Posts: 27
Registered: 3/17/00
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 2:27 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
You should be catching the Exception by const reference.

Why? As far as I know it doesn't make any difference. It is not possible to throw a const exception anyway.

Also, it is NOT safe to call MessageBox() (or any other UI function) in
DllEntryPoint():

I was not aware of that. But you can remove the call to MessageBox() from my example. It crashes before it gets to it anyway.
I usually don't have any code in the DllEntryPoint(). I was just trying to make the simplest example that reproduces the crash.


Thanks for the link.

Ivan Johansen
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 3:36 PM   in response to: Ivan Johansen in response to: Ivan Johansen
Ivan Johansen wrote:

You should be catching the Exception by const reference.

Why? As far as I know it doesn't make any difference.

Actually it does affect how the compiler generates code for catching
and managing the Exception object.

It is not possible to throw a const exception anyway.

No, you can't throw a const reference, but you can (and should)
catch a non-POD type by const reference. Just like you can pass a
non-const value to a const function parameter. Same goes with an
exception handler.

--
Remy Lebeau (TeamB)
Ivan Johansen

Posts: 27
Registered: 3/17/00
Re: Access violation when throwing exception in 64 bit DLL  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 31, 2018 12:11 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Actually it does affect how the compiler generates code for catching
and managing the Exception object.

How does it affect the generated code? As far as I know it shouldn't. And it is perfectly legal to change the caught object. But I agree with catching by reference to avoid slicing and making a copy of the object.

Or is this a new thing? I admit I have very limited knowledge about changes since C++98.

Ivan Johansen
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02