- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
We've had trouble in the past with I/O and string concatenation operations coring when our application is run as a DLL in a mixed language multithreaded environment. Compaq recommended we call for_rtl_init in the main, which we did and all was well.
Now we're being run in a similar environment where we no longer have any control over the main. Calling for_rtl_init from our DLL does not solve the problem.
For example, the first read cores at:
The first write cores at:
Ideas anyone?
Thanks,
Brian.
We've had trouble in the past with I/O and string concatenation operations coring when our application is run as a DLL in a mixed language multithreaded environment. Compaq recommended we call for_rtl_init in the main, which we did and all was well.
Now we're being run in a similar environment where we no longer have any control over the main. Calling for_rtl_init from our DLL does not solve the problem.
For example, the first read cores at:
POS150GM! for__access_threadstor_threads + 78 bytes POS150GM! for__once_private + 70 bytes POS150GM! for__access_threadstor_threads + 18 bytes POS150GM! for__io_return + 236 bytes POS150GM! for_read_seq_fmt + 1045 bytes ...my Fortran code...
The first write cores at:
POS150GM! for__access_threadstor_threads + 78 bytes POS150GM! for__once_private + 70 bytes POS150GM! for__access_threadstor_threads + 18 bytes POS150GM! for__acquire_threadstor_threads + 13 bytes POS150GM! for__acquire_lun + 102 bytes POS150GM! for_write_int_fmt + 26 bytes ...my Fortran code...
Ideas anyone?
Thanks,
Brian.
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you reading or writing to a console? If so, by default, DLLs don't have a console, and you need to create one. (see AllocConsole())
If there is a different problem, could you post a little code?
- Lorri
If there is a different problem, could you post a little code?
- Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually, the problem can occur just by performing a simple string concatenation (e.g., 'foo'//'bar'). It seems that concatenation and I/O share common low level routines, and these must be initialized by calling the run-time initialization routine from the main.
What I am hoping to find is some way that the for_rtl_init can be called from a DLL (and work), or some alternate technique that will initialize the run-time library code.
We're running 6.6B, so a compiler upgrade is not an option.
What I am hoping to find is some way that the for_rtl_init can be called from a DLL (and work), or some alternate technique that will initialize the run-time library code.
We're running 6.6B, so a compiler upgrade is not an option.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What do you refer to as "main"? Main program's entry point (Program/void main())?
No guaranteees at all, but you might try to supply your own DllMain (aka DllEntryPoint) and call for_rtl_init from there. Here's mine:
Jugoslav
No guaranteees at all, but you might try to supply your own DllMain (aka DllEntryPoint) and call for_rtl_init from there. Here's mine:
integer function DllEntryPoint(hModule, fdwReason, lpvReserved) !DEC$ATTRIBUTES STDCALL, ALIAS:"_DllEntryPoint@12":: DllEntryPoint use dfwin, only: InitializeCriticalSection implicit none integer, intent(in):: hModule, fdwReason, lpvReserved select case (fdwReason) case(DLL_PROCESS_ATTACH) hDMSDll = hModule call SetWrite() call InitializeCriticalSection(LOC(CS)) DllEntryPoint=1 case default DllEntryPoint=1 end select end function DllEntryPointIf I recall correctly, you must specify DllEntryPoint@8 at Project Settings/Link/Entry point symbol. For possible fdwReasons, see documentation.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We've already tried this, but from the C++ side, without any success. The code we used was as follows:
We are now going to try plan B, which is to run our Fortran code through F2C and compile using VC++. Messy and time consuming and no guarantees, but we're desperate. I'll post our results, and keep a watch on this thread for other suggestions.
Brian.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: for_rtl_init_(0,0); break; case DLL_PROCESS_DETACH: for_rtl_finish_(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: default: break; } return TRUE; }The online help for the for_rtl_init function states that it must be called from the C/C++ main entry (and this appears accurate based on our results).
We are now going to try plan B, which is to run our Fortran code through F2C and compile using VC++. Messy and time consuming and no guarantees, but we're desperate. I'll post our results, and keep a watch on this thread for other suggestions.
Brian.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
However... Let me see...
I have a setup where a dll (linked against multi-threaded version of the dll) is called from a Delphi caller. I linked it against multi-threaded version of the dll and it indeed crashed on the first string operation. Then I placed a call to for_rtl_init_ in aforementioned DllMain (written in Fortran) on DLL_PROCESS_ATTACH and it worked like charm (didn't try reentrant call though).
Perhaps a stupid question, but have you verified that your DllMain was actually called? I believe you have to set up "Entry point symbol" in linker settings. Maybe the language has something to do with it -- there's a lot of RTL happening behind the scenes (and I admit I don't know exactly what it is).
Jugoslav
I have a setup where a dll (linked against multi-threaded version of the dll) is called from a Delphi caller. I linked it against multi-threaded version of the dll and it indeed crashed on the first string operation. Then I placed a call to for_rtl_init_ in aforementioned DllMain (written in Fortran) on DLL_PROCESS_ATTACH and it worked like charm (didn't try reentrant call though).
Perhaps a stupid question, but have you verified that your DllMain was actually called? I believe you have to set up "Entry point symbol" in linker settings. Maybe the language has something to do with it -- there's a lot of RTL happening behind the scenes (and I admit I don't know exactly what it is).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not a stupid question at all! We double checked that the DLL entry point was correctly set (it was). We then added a MessageBox call following the for_rtl_init one. Our message box appeared, followed shortly thereafter by a core.
Thanks for the suggestion.
I've placed a FortranBug.zip file on our FTP site containing a DevStudio workspace that demonstrates the problem with just a few files. We're using DevStudio 6, VC++6.0 SP5, and Compaq VF6.6.B.
We have found that the problem can be corrected by performing Fortran I/O in the main program. Uncomment the DUMMY call in main.cpp, add the dummy.for file to the bugexe.dsp project and rebuild. Problem is gone!
But unfortunately, in our real-world application we didn't write the main program and so we have no opportunity to call a dummy routine to perform Fortran I/O.
Ideas?
Brian.
Thanks for the suggestion.
I've placed a FortranBug.zip file on our FTP site containing a DevStudio workspace that demonstrates the problem with just a few files. We're using DevStudio 6, VC++6.0 SP5, and Compaq VF6.6.B.
bugexe.dsw The main DevStudio workspace bugexe/bugexe.dsp Main program project file main.cpp C++ main program dummy.for Fortran file for testing mydll/mydll.dsp The DLL project file mydll.for DLL Fortran code that will core mydllc.cpp DLL main entryLoad the bugexe.dsw workspace, build all and run it and you will get a core dump in mydll.for.
We have found that the problem can be corrected by performing Fortran I/O in the main program. Uncomment the DUMMY call in main.cpp, add the dummy.for file to the bugexe.dsp project and rebuild. Problem is gone!
But unfortunately, in our real-world application we didn't write the main program and so we have no opportunity to call a dummy routine to perform Fortran I/O.
Ideas?
Brian.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
True. What I didn't try last time was to create a thread internally.
I did few experiments and your workspace (appears to) works flawlessly when mydll is linked against multithreaded DLL versions of Fortran and C++ RTL's (DFORMD.dll) (FWIW, I replaced CreateThread with _beginthreadex as well, just in case). Is that an option?
I suggest you send a bug report to Compaq. Your workspace is a cut-down example that vendors, quote, "tend to love". I'm not so versatile in such things to tell you whether the core dump is supposed to be normal under such circumstances. A usual recommendation is to link dlls against DLL RTLs, but I don't know what are grounds for that (situation like yours?).
Jugoslav
I did few experiments and your workspace (appears to) works flawlessly when mydll is linked against multithreaded DLL versions of Fortran and C++ RTL's (DFORMD.dll) (FWIW, I replaced CreateThread with _beginthreadex as well, just in case). Is that an option?
I suggest you send a bug report to Compaq. Your workspace is a cut-down example that vendors, quote, "tend to love". I'm not so versatile in such things to tell you whether the core dump is supposed to be normal under such circumstances. A usual recommendation is to link dlls against DLL RTLs, but I don't know what are grounds for that (situation like yours?).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are right -- we could link against DLL versions of the Fortran and C++ RTL's, but we have had bad experiences doing this in the past. I didn't mention that our software is run just about everywhere in the world (except Elbonia, thankfully) and we've had to use static linking to avoid a host of run-time issues. We began statically linking in the mid '90s and since then OS related issues have been minimized.
We will investigate the possibility that the "other vendor" main program, to which we are linked, uses DLL RTL's at the same level or higher than we do. If so, we have a solution!
I won't have an answer on this for about 2 weeks. I'll post again once I know.
Thanks,
Brian.
We will investigate the possibility that the "other vendor" main program, to which we are linked, uses DLL RTL's at the same level or higher than we do. If so, we have a solution!
I won't have an answer on this for about 2 weeks. I'll post again once I know.
Thanks,
Brian.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What is a "core?"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
http://info.astrian.net/jargon/terms/c/core_dump.html.
Jugoslav
P.S. Add the site to your Favorites -- it's great :-).
Jugoslav
P.S. Add the site to your Favorites -- it's great :-).

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page