Possible Deadlock on Calling FreeLibrary - c++

I have to write a DLL in Delphi XE7. I want to use TParallel.For in the DLL. The DLL is loaded into a C++ application, where everything works. However, when the application terminates, or a call to FreeLibrary is made, the application hangs. If I remove all the TParallel.For loops and replace them with standard loops, the application exits normally.
The TParallel.For loops are very simple:
TParallel.For(0, inImage.Height -1,
Procedure(ty : integer)
begin
SomeProcedure(ty);
end);
If I create a Delphi application with exactly the same code, everything works perfectly.
After doing a lot of research and debugging, it looks like there is a deadlock which is preventing the C++ application from exiting when FreeLibrary is called, but I can't find where the problem is in TParallel.
Just to summarise the situation:
The TParallel.For loops all complete and produce the correct results.
The exact same TParallel.For code in a Delphi .exe works correctly.
The DLL is loaded and the functions are called and perform correctly from within the C++ application.
The C++ application will exit correctly if there are no TParallel.For loops.
The C++ application will hang if there are TParallel.For loops.
I am guessing that there is a deadlock which occurs when FreeLibrary is called.
If I use the OTL threading library, everything works as it should.
My questions are:
Has anyone else experienced this behaviour?
What is a good debugging strategy to find a deadlock in this situation?
Any advice is greatly appreciated.
UPDATE
OK, so if you want Minimal, Complete and Verifiable example, here you go (thank you Stephen Ball):
library ADelphiDLL;
uses
System.SysUtils, System.Classes, Threading, SyncObjs;
function IsPrime (N: Integer): Boolean;
var
Test: Integer;
begin
IsPrime := True;
for Test := 2 to N - 1 do
if (N mod Test) = 0 then
begin
IsPrime := False;
break; {jump out of the for loop}
end;
end;
function Prime(Max : integer) : boolean;
var
tot : integer;
begin
tot := 0;
TParallel.For(1, Max, procedure (I: Integer)
begin
if IsPrime (I) then
TInterlocked.Increment (Tot);
end);
return true;
end;
exports Prime;
begin
IsMultiThread := True;
end.
in C++:
#include "stdafx.h"
typedef bool(__stdcall *primesf)(int);
void main()
{
HINSTANCE hGetDLL = LoadLibrary(L"ADelphiDLL.dll");
primesf primes = (primesf)GetProcAddress(hGetProcIDDLL, "Primes");
bool result = primes(100);
FreeLibrary(hGetDLL);// <-- Hangs here forever
}
In response to the very "helpful" comments, "there is a defect in the code " and "debug it yourself", thank you, that is what I have been doing for a too long a time. So, if there is no help forthcoming here, I will try and get permission to switch to OTL, which does work in the DLL in question.
UPDATE 2
OTL works exactly as expected. So, yes, there is a "defect in the code". I give up. I will recommend abandoning Delphi altogether and then we can move everything over to C++ and C#. That has to be a much better short (and long term) solution.

I have seen an issue similar to this, although i was using Delphi 10.0 Seattle, and a Delphi EXE loading a Delphi DLL.
Anyway, the solution that I came up with is the following:
In your Delphi DLL, first create your own thread pool.
Use the overloaded version of TParallel.For that takes a thread pool object as its last parameter, and provide your own thread pool object.
Before unloading your Delphi DLL, make sure to free your thread pool object.
This approach solved the problem for me.
TParallel.For documentation:
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Threading.TParallel.For
Example pseudo-code:
MyPool: TThreadPool;
MyPool := TThreadPool.Create;
TParallel.For(1, Max, procedure (I: Integer)
begin
if IsPrime (I) then
TInterlocked.Increment (Tot);
end,
MyPool
);
MyPool.Free;

Related

AccessViolationException calling native C++ code from managed C++ (wrapper for ASP.NET)

I have a ASP.NET web application that needs access to a function in a native C++ DLL. To do this, I wrapped the native C++ code using a managed C++ DLL. Calling the native function from the managed code, however, results in a System.AccessViolationException. I do not have to the native code, but it will write to the file system (logs), which was my first guess, but according to other SO answers the AccessViolationException is caused by memory issues.
The code is pretty simple, this is the unshortened version:
#include <msclr\marshal_cppstd.h>
#define AS_NATIVE_STRING(managed_string) msclr::interop::marshal_as<std::string>(managed_string)
#define AS_MANAGED_STRING(native_string) msclr::interop::marshal_as<String^>(native_string)
ReturnStruct ManagedClass::execute_managed(String ^param1, String ^param2)
{
auto param1_native = AS_NATIVE_STRING(param1);
auto param2_native = AS_NATIVE_STRING(param2);
// here I get the exception:
auto result = _wrapped_api->execute_native(param1_native, param2_native);
if (is_error_string(result.first))
throw gcnew System::Exception(AS_MANAGED_STRING(result.second));
auto result1 = AS_MANAGED_STRING(result.first);
auto result2 = AS_MANAGED_STRING(result.second);
return ReturnStruct(result1, result2);
}
Any hints on what could be causing it? I did indeed look at similar questions, but no answer seemed to really fit my problem.
Edit:
Using HandleProcessCorruptedStateExceptionsAttribute I was able to determine the error message of the AccessViolationException: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
After further investigation, I have come to the conclusion, that I basically cannot fix this on my end. I created a mock version of the DLL myself to be able to step in and see if the type conversion is correct and the parameters contain the correct strings. This was the case. This does not really help me, but maybe someone else might find a problem in his/her code with this approach.
I will just contact the authors of the wrapped api.

How force unload library in C++ (Dev C++ compiler)?

I saw a Delphi (Object Pascal) code that force unloads any module (dll) that is loaded inside my software. Then with base in this code, I'm wanting and needing of something similar now in C++ (Dev C++).
Someone can help me please?
Here is Delphi code that I saw:
procedure ForceRemove(const ModuleName: string);
var
hMod: HMODULE;
begin
hMod := GetModuleHandle(PChar(ModuleName));
if hMod=0 then
exit;
repeat
until not FreeLibrary(hMod);
end;
The functions
HMODULE GetModuleHandle(LPCTSTR modulename)
BOOL FreeLibrary(HMODULE)
are functions of the Windows API. It can be called from any language that supports programming against the Windows API, as C++
Only recommendation: Remove the loop (the repeat until not ...) in your sample above. It should be replaced by code that interprets the return value of the call to FreeLibrary, documentation here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx
The DLL will be unloaded from memory (that is to say, the address space of the executing process), as soon as its per-process reference count goes zero; you cannot force unloading a DLL globally by repeatedly executing FreeLibrary() if another process still holds a reference.
EDIT: included a direct translation of OP's sample into a C++ snippet:
void ForceRemove(LPCTSTR ModuleName)
{
HMODULE hMod;
hMod = ::GetModuleHandle(ModuleName);
if(hMod==0)
return;
/* DISCLAIMER potentially infinite loop
* not advisable in production code,
* included by request of the OP to
* match his original */
while(::FreeLibrary(hMod));
}

Asynchronous call to MATLAB's engEvalString

Edit 2: Problem solved, see my answer.
I am writing a C++ program that communicates with MATLAB through the Engine API. The C++ application is running on Windows 7, and interacting with MATLAB 2012b (32-bit).
I would like to make a time-consuming call to the MATLAB engine, using engEvalString, but cannot figure out how to make the call asynchronous. No callback is necessary (but would be nice if possible).
The following is a minimum example of what doesn't work.
#include <boost/thread.hpp>
extern "C" {
#include <engine.h>
}
int main()
{
Engine* eng = engOpen("");
engEvalString(eng,"x=10");
boost::thread asyncEval(&engEvalString,eng,"y=5");
boost::this_thread::sleep(boost::posix_time::seconds(10));
return 0;
}
After running this program, I switch to the MATLAB engine window and find:
» x
x =
10
» y
Undefined function or variable 'y'.
So it seems that the second call, which should set y=5, is never processed by the MATLAB engine.
The thread definitely runs, you can check this by moving the engEvalString call into a local function and launching this as the thread instead.
I'm really stumped here, and would appreciate any suggestions!
EDIT: As Shafik pointed out in his answer, the engine is not thread-safe. I don't think this should be an issue for my use case, as the calls I need to make are ~5 seconds apart, for a calculation that takes 2 seconds. The reason I cannot wait for this calculation, is that the C++ application is a "medium-hard"-real-time robot controller which should send commands at 50Hz. If this rate drops below 30Hz, the robot will assume network issues and close the connection.
So, I figured out the problem, but would love it if someone could explain why!
The following works:
#include <boost/thread.hpp>
extern "C" {
#include <engine.h>
}
void asyncEvalString()
{
Engine* eng = engOpen("");
engEvalString(eng,"y=5");
}
int main()
{
Engine* eng = engOpen("");
engEvalString(eng,"x=10");
boost::thread asyncEvalString(&asyncEvalString);
boost::this_thread::sleep(boost::posix_time::seconds(1));
engEvalString(eng,"z=15");
return 0;
}
As you can see, you need to get a new pointer to the engine in the new thread. The pointer returned in asyncEvalString is different to the original pointer returned by engOpen in the main function, however both pointers continue to operate without problem:
» x
x =
10
» y
y =
5
» z
z =
15
Finally, to tackle the problem of thread safety, a mutex could be set up around the engEvalString calls to ensure only one thread uses the engine at any one time. The asyncEvalString function could also be modified to trigger a callback function once the engEvalString function has been completed.
I would however appreciate someone explaining why the above solution works. Threads share heap allocated memory of the process, and can access memory on other threads' stacks (?), so I fail to understand why the first Engine* was suddenly invalid when used in a separate thread.
So according to this Mathworks document it is not thread safe so I doubt this will work:
http://www.mathworks.com/help/matlab/matlab_external/using-matlab-engine.html
and according to this document, engOpen forks a new process which would probably explain the rest of the behavior you are seeing:
http://www.mathworks.com/help/matlab/apiref/engopen.html
Also see, threads and forks, think twice about mixing them:
http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them

Unhandled Exception in Rad Studio Debugger Thread

I have a large application that recently started exhibiting rather strange behavior when running in a debugger. First, the basics:
OS: Windows 7 64-bit.
Application: Multithreaded VCL app with many dlls, bpls, and other components.
Compiler/IDE: Embarcadero RAD Studio 2010.
The observed symptom is this: While the debugger is attached to my application, certain tasks cause the application to crash. The particulars are furthermore perplexing: My application stops with a Windows message saying, "YourApplication has stopped working." And it helpfully offers to send a minidump to Microsoft.
It should be noted: the application doesn't crash when the debugger is not attached. Also, the debugger doesn't indicate any exceptions or other issues while the application is running.
Setting and stepping through breakpoints seems to affect the point at which the application crashes, but I suspect that is a symptom of debugging a thread other than the problematic one.
These crashes also occur on the computers on my colleagues, with the same behavior I observe. This leads me to not suspect a failed installation of something on my computer particularly. My colleagues experiencing the issue are also running Windows 7 64-bit. I have no colleagues not experiencing the issue.
I've collected an analyzed a number of full dumps from the crashes. I discovered that the failure was actually happening in the same place each time. Here is the exception data from the dumps (it is always the same, except of course the ThreadId):
Exception Information
ThreadId: 0x000014C0
Code: 0x4000001F Unknown (4000001F)
Address: 0x773F2507
Flags: 0x00000000
NumberParameters: 0x00000001
0x00000000
Google reveals that Code 0x4000001F is actually STATUS_WX86_BREAKPOINT. Microsoft unhelpfully describes it as "An exception status code that is used by the Win32 x86 emulation subsystem."
Here are the stack details (which don't seem to vary):
0x773F2507: ntdll.dll+0x000A2507: RtlQueryCriticalSectionOwner + 0x000000E8
0x773F3DAB: ntdll.dll+0x000A3DAB: RtlQueryProcessLockInformation + 0x0000020D
0x773D2ED9: ntdll.dll+0x00082ED9: RtlUlonglongByteSwap + 0x00005C69
0x773F3553: ntdll.dll+0x000A3553: RtlpQueryProcessDebugInformationRemote + 0x00000044
0x74F73677: kernel32.dll+0x00013677: BaseThreadInitThunk + 0x00000012
0x77389F02: ntdll.dll+0x00039F02: RtlInitializeExceptionChain + 0x00000063
0x77389ED5: ntdll.dll+0x00039ED5: RtlInitializeExceptionChain + 0x00000036
It is worth noting that there appears to be a function epilog at 0x773F24ED, which rather suggests that the RtlQueryCriticalSectionOwner is a red herring. Likewise, a function epilog casts doubt on RtlQueryProcessLockInformation. The 0x5C69 offset casts doubt on the RtlUlonglongByteSwap. The other symbols look legit, though.
Specifically, RtlpQueryProcessDebugInformationRemote looks legitimate. Some people on the internet (http://www.cygwin.com/ml/cygwin-talk/2006-q2/msg00050.html) seem to think that it is created by the debugger to collect debug information. That theory seems sound to me, since it only seems to appear when the debugger is attached.
As always, when something breaks, something changed that broke it. In this case, that something is dynamically loading a new dll. I can cause the crash to stop happening by not dynamically loading the particular dll. I'm not convinced that the dll loading is related, but here are the details, just in case:
The dll source is C. Here are the compile options that are not set to the default:
Language Compliance: ANSI
Merge duplicate strings: True
Read-only strings: True
PCH usage: Do not use
Dynamic RTL: False
(The Project Options say False is default for Dynamic RTL, though it was set to True when I created the dll project.)
The dll is loaded with LoadLibrary and freed with FreeLibrary. All seems to be fine with the loading and unloading of the module. However, shortly after the library is unloaded (with FreeLibrary), the aforementioned thread crashes the program. For debugging, I removed all actual calls to the library (including, for more testing, DllMain). No combination of calls or not calls, DllMain or no DllMain, or anything else seemed to alter the behavior of the crash in any way. Simply loading and unloading the dll invokes the crash later on.
Furthermore, changing the dll to use the Dynamic RTL also causes the debugger thread crash to cease. This is undesirable because the compiled dll really should be usable without CodeGear Runtime available. Also, dll size is important. The C code contained in the dll does not make use of any libraries. (It includes no headers, even standard library headers. No malloc/free, no printf, no nothin'. It contains only functions that depend exclusively on their inputs and do not require dynamic allocation.) It is also undesirable because "fixing" a bug by changing stuff until it works without understanding why it works is really never a good plan. (It tends to lead to bug recurrences and strange coding practices. But really, at this point, if I can't find anything else, I may admit defeat on this count.)
And finally, my issue may be related to one of these issues:
System error after debugging multithreaded applications
Program and debugger quit without indication of problem
Any ideas or suggestions would be appreciated.
I solved the above mentioned problem by using a modified version of the PatchINT3 workaround, which was published in 2007 for BDS 2006:
procedure PatchINT3;
const
INT3: Byte = $CC;
NOP: Byte = $90;
var
NTDLL: THandle;
BytesWritten: DWORD;
Address: PByte;
begin
if Win32Platform <> VER_PLATFORM_WIN32_NT then
Exit;
NTDLL := GetModuleHandle('NTDLL.DLL');
if NTDLL = 0 then
Exit;
Address := GetProcAddress(NTDLL, 'RtlQueryCriticalSectionOwner');
if Address = nil then
Exit;
Inc(Address, $E8);
try
if Address^ <> INT3 then
Exit;
if WriteProcessMemory(GetCurrentProcess, Address, #NOP, 1, BytesWritten)
and (BytesWritten = 1) then
FlushInstructionCache(GetCurrentProcess, Address, 1);
except
//Do not panic if you see an EAccessViolation here, it is perfectly harmless!
on EAccessViolation do
;
else
raise;
end;
end;
Call this routine once after you have loaded the DLL in your thread. The patch fixes a user breakpoint in ntdll.dll version 6.1.7601.17725 and changes it to a NOP.
If there is no user breakpoint (INT3 (=$CC) opcode) at the expected address, the patch routine does nothing and exits.
Hope that helps,
Andreas
Footnote
The original source of PatchINT3 can be found here:
http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.non-technical/2007-01/msg04431.html
Footnote2
The same function in C++:
void PatchINT3()
{
unsigned char INT3 = 0xCC;
unsigned char NOP = 0x90;
if (Win32Platform != VER_PLATFORM_WIN32_NT)
{
return;
}
HMODULE ntdll = GetModuleHandle(L"NTDLL.DLL");
if (ntdll == NULL)
{
return;
}
unsigned char *address = (unsigned char*)GetProcAddress(ntdll,
"RtlQueryCriticalSectionOwner");
if (address == NULL)
{
return;
}
address += 0xE8;
try
{
if (*address != INT3)
{
return;
}
unsigned long bytes_written = 0;
if (WriteProcessMemory(GetCurrentProcess(), address, &NOP, 1,
&bytes_written) && (bytes_written == 1))
{
FlushInstructionCache(GetCurrentProcess, address, 1);
}
}
catch (EAccessViolation &e)
{
//Do not panic if you see an EAccessViolation
//here, it is perfectly harmless!
}
catch(...)
{
throw;
}
}
Just an idea...
Perhaps you need to close in on the crashing thread. The state that you are observing seems to be a bit after the actual error.
First, your stack traces seems incomplete to me. What is the base root of the stack of that thread? What was the origin of that thread?
And, in the VS debugger there is the possibility to break on exceptions, (Debug->Exceptions...->[Add]). Then all threads will freeze at the moment the exception occurs. I dunno about RAD, but the trick to do it programatically seems to be WaitForDebugEvent().
I could be wrong but I think there is a fair chance that the bug is in the debugger not your code. In that case an uggly workaround is IMHO fully forgivable. Good luck!
I cannot answer this because I cannot see the code...
But...
1) In Borland C++ at least with C++ from BDS there can be a provable problem with the realloc function in multithreaded library. Is your C++ code using realloc?
2) The stack you are showing is more than likely being called as a result of your code actually hitting a "CALL BAD_ADRESS" and that can happen as a result of a bug in your own code. In other words, in the DLL you load, there is likely a function that is doing something that is overwriting the executable code in your program with junk, and then when the now junk section runs, it crashes.
Another way is if something in the C++ dll is modifying the stack below where it runs, and then your code is hitting that later.
3) Check out the CPU flags settings for your DLL. Borland libraries sometimes use conflicting CPU flags upon entry and you might need to save and restore before calling into the DLL. For example if you call a VST plugin made with C++ from Delphi and do not set the flags properly, you can get subsequent divide by zero errors from the VST plugin which was compiled with that exception turned off.
We had the same issue today. In our case the crash happens if having a breakpoint after call to TOpenDialog->Execute() (which is using dialog from shell32.dll I think) (Windows 7 x64, C++ Builder XE2)
After uninstalling iCloud (v2.1.0.39), the issue was resoved.
Unfortunately we are still looking into similar issue our customers are having some times with our release product under Windows Vista. After selecting the file using TOpenDialog, the application crashes in gdiplus.dll with Access violation, removing the iCloud seems to also resolve the issue.

C++ DLL which can inform a calling program about its progress

My boss wants me to write a DLL in C++ (MSVC++2010) which can perform a Volume Shadow Copy which he can call from VB6 (or at a later point other languages) and which can give status updates back while it is not finished. He calls it "events".
I have the feeling that I finally need to learn COM (I'd rather not ...) ... also, a callback function comes to my mind, but it's surely impossible to hand over function pointers from VB6 to C++?
Can someone outline what I have to learn and how this can be accomplished, with or without COM?
EDIT:
to answer a question, the work flow is supposed to be:
VB6 app determines which files to back up
I am given a path and make a temporary volume shadow copy which includes this path and give back a mount point (or similar)
during this step, I regularly tell the VB6 app how far I am
VB6 app makes backup of shadow copy and then deletes shadow copy.
You can pass a pointer to your "display progress" function from the VB app to the C++ DLL app using the AddressOf operator:
Declare Function CallMyDll ...
Sub DisplayStatus(ByVal SomeParameter As Long)
' ...
End SUb
Sub DoSomething()
Call CallMyDll(AddressOf DisplayStatus)
End Sub
Some not so obvious gotchas:
You have to declare your C++ function pointer using the __stdcall calling convention. (Thanks, Alexandre C!)
In your VB callback function, explicitly mark your parameters as by-value using the keyword ByVal. Similarly, in your C++ function pointer, don't mark your parameters as by-reference.
If you want to pass a string to the callback, or retrieve a string from it, you have to take into consideration that VB Strings are not equal to C char*s, C++ std::strings, or Microsoft's CStrings. VB Strings must be mapped to Microsoft's rather obscure BSTR data type.
I forgot a very important thing: Your callback has to be inside a VB Module (i.e., it has to be a "mere function", not a class' or a form's method).
Your boss can call functions exported by a DLL with the Declare statement. That doesn't scale well but is fine for a simple API. Your function should be exported with the extern "C" and __declspec(dllexport) declarators, use the __stdcall calling convention and use only simple argument types.
When it has to provide these status updates?
While setting up VSS? Or while backing up the data and such?
In the latter case VSS just returns a path, which can be used
directly from VB.
But for setup... it might make sense too, because it can be fairly slow,
but I guess you can turn it into a state machine - put all the VSS API calls
into a big switch() and make a function which would call them one by one and
update the state var.
Update: I mean something like this.
Init() and Step() are your functions exported by your dll and called from VB.
Alternatively, you can spawn a thread to do all that (still in the dll) and return
status updates after like Sleep(100) in Step().
int s; // state
int Init( void ) { s=0; }
int Step( void ) {
switch( s ) {
default: break;
case 0:
CoInitialize(0); break;
case 1:
r = CreateVssBackupComponents(&vssc);
if( FAILED(r) ) s=-1;
if( vssc==0 ) s=-2;
break;
case 2:
r = vssc->InitializeForBackup();
if( FAILED(r) ) s=-3;
break;
case 3:
r = vssc->SetBackupState( FALSE, FALSE, VSS_BT_COPY, FALSE );
if( FAILED(r) ) s=-4;
break;
[...]
}
s += (s>=0);
}
I would do the job without COM. Instead, I'd have the VB part send a window handle to the DLL, and the DLL will post a message to the window telling its progress.
You could use COM, but that's kind of in the range of swatting a fly with a sledgehammer.
Take the unix-y route. Create a PROGRAM that performs the copy and outputs a progress indicator to std out. Make the VB app parse this output to grab the completion percentage.
I would do this:
the VB app calls the function in your DLL asking to start the shadow copy. Your Dll starts a thread that performs the shadow copy and returns an ID (a thread id?) back to the VB app
The VB app calls periodically a function "Progress" in your DLL passing the operation ID received before: the progress function returns an integer 0-100 to indicate the progress
This way the VB app can launch several operations in parallel.
The thread that performs the copy should update a "progress" variable every now and then.
Another function in the DLL that stops the copy would be useful too.