Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.

Public Report
Report From: Delphi-BCB/VCL    [ Add a report in this area ]  
Report #:  113043   Status: Open
Show of TForm on DLL will make loader app crash on closing
Project:  C++Builder Build #:  4, ... XE3
Version:    17.1 Submitted By:   Paul F
Report Type:  Issue Date Reported:  2/25/2013 2:28:43 AM
Severity:    Extreme corner case Last Updated: 2/26/2013 6:43:51 PM
Platform:    All versions Internal Tracking #:   36650
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 60
Description
Problem was detected with any TForm within a DLL, but happen to also trigger with a simple InputBox.

Both DLL and Loader App must be monolithic
(Link With Dynamic RTL: false; Link with runtime packages: false)

Yes, they'll be bigger but no hassle deploying/updating extra BPL's.
Care is taken just to keep DLL and Loader within the very same compiler version (including update packs) - no ABI issues.

It is a regression because it has been working reliably since BCB4 up to RS2010 (at least).
Steps to Reproduce:
1. Create DLL with any TCustomForm
File - New - Other - C++Builder Projects - Dynamic-link Library - Ok
- C++,
- Target Framework: Visual Component Library
- VC++ Style DLL: Checked
- Project - Options - C++ Linker - Link with Dynamic RTL: false
- Project - Options - Packages - Runtime Packages - Link with runtime packages: false

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}

extern "C" void __declspec(dllexport) GetInputBox(TApplication *LoaderApp)
{
  TApplication *DLL_OwnApp = Application; // back up own App ptr
  Application = LoaderApp;
  InputBox("TCustomForm within DLL", "Dummy input:", "Foo bar");
  Application = DLL_OwnApp; // restore it
}

3. Save project of DLL as InputBox_DLL

4. Create Loader application with a TButton
File - New - VCL Forms Application - C++Builder - Ok,
- Project-Options-C++ Linker-Link with Dynamic RTL: false
- Project-Options-Packages-Runtime Packages-Link with runtime packages: false

5. Drop a TButton on the form and use the following code to invoke the InputBox from DLL:
  #if !defined(_auto)
    #if _WIN64 && __clang__
      #define _auto(Name, Type) auto Name = Type
    #else
      #define _auto(Name, Type) decltype(Type) Name = Type
    #endif
  #endif

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if (_auto(const hDLL, (HINSTANCE)SafeLoadLibrary("InputBox_DLL.dll"))) {
    if (_auto(const GetInputBox, reinterpret_cast<void (*)(TApplication*)>
          (GetProcAddress(hDLL, "_GetInputBox")))) {
      GetInputBox(Application); // Would also cause a crash if it were any TForm
    }
    FreeLibrary(hDLL);
  }
  MessageDlg("Press any key to close the loader application and crash!",
    mtInformation, TMsgDlgButtons() << mbOK, 0);
  Close();

  /*
  -----
  Debugger Exception Notification
  ----
  Project InputBox_Loader.exe raised exception class $C0000005 with message
    'access violation at 0x0052e835: write of address 0x02eff448'.
  */
}
Workarounds
None
Attachment
InputBox_Crash.zip
Comments

Tomohiro Takahashi at 2/25/2013 6:48:40 AM -
> extern "C" void __declspec(dllexport) GetInputBox(TApplication *LoaderApp)
> {
>   TApplication *DLL_OwnApp = Application; // back up own App ptr
>   Application = LoaderApp;
> ...
>       GetInputBox(Application); // Would also cause a crash if it were any TForm
If you turn off Dynamic RTL and Runtime packages on both .dll and .exe, .dll and .exe include memory manager and VCL RTL in it respectively.
So, in such case, we can not(must not) share TApplication instance, which is part of VCL/RTL, between the .dll and .exe.

Paul F at 2/25/2013 7:27:44 AM -
The workaround is quite less than ideal. Fact remain that code that worked under RS2010 won't anymore for XE3.

Server Response from: ETNACODE01