Page 1 of 1
Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 3:57 am
by RichAlgeni
This is an issue that seems to have arisen since the beginning of the year in both Windows Server 2008 and 2012.
I do not believe it is a bug, I believe it is a change Microsoft has made. It has to do with using a list, map or dimensioned array at the beginning of a dll, which is NOT inside a procedure. I have for a number of years now utilizing PureBasic includes for both mainline routines and dlls. Since I have used them, they have worked fine. Until last Thursday!
While troubleshooting a server database access issue, and not having much success, I installed Windows updates for a Windows Server 2008 machine. Updates had not been installed since just after Christmas. It turns out that the database access issue was not on the server, but a bad odbc driver on a client machine. Anyway, after the server was rebooted, a number of my programs had crashed. It took a number of hours to pin the problems down to my dll's. After a number of hours testing and troubleshooting this weekend, I found the issue. Any dll's of mine called by any mainline routine was crashing, including IIS, Internet Information Server. After creating a barebones calling process, and my main include process to load various variables and constants I use. After 59 attempts of removing various pieces of code (I used the compile count), I found the problem. I used a list process to add included programs to the list of programs the dll was compiled with. The dll crashed the mainline routine when the mainline routine tried to load it.
I tested with a list, a map and dimensioned array. All crashed the mainline routine. When I changed this code to simply append the program name to the program list. The mainline routine no longer crashed. I tested the same scenario on a Windows 2012r2 machine that had also not loaded updates since just after Christmas, and had no problems. Once updates were loaded, the mainline processes also crashed when attempting to open a dll that included a AddElement() statement.
As far as I can tell, nothing else changed on these two machines, other than Windows updates. I have several versions of PureBasic loaded on my development machine, and was able to test back to version 5.21, from 5.42. The different versions made no difference!
Re: Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 3:47 pm
by RichAlgeni
Here is the dll I used to test, simply comment out lines 10 and 11, recompile and test again.
Code: Select all
; ------------------------------------------------------------
; Program name: test_call_dll.pb
; Purpose: 64 bit dll to test a calling problem!
; ------------------------------------------------------------
EnableExplicit
Global NewList programList.s()
AddElement(programList())
programList() = "test_call_dll.pb"
; ************************************************************************************
; dll initialization procedure
; ************************************************************************************
ProcedureDLL.i AttachProcess(instance.i)
EndProcedure
; ************************************************************************************
; dll detach process
; ************************************************************************************
ProcedureDLL.i DetachProcess(instance.i)
EndProcedure
; ************************************************************************************
; dll attach thread
; ************************************************************************************
ProcedureDLL.i AttachThread(instance.i)
EndProcedure
; ************************************************************************************
; dll detach thread
; ************************************************************************************
ProcedureDLL.i DetachThread(instance.i)
EndProcedure
; ************************************************************************************
; test procedure called inside the dll
; ************************************************************************************
ProcedureDLL.i test_dll_procedure(instance.i)
ProcedureReturn #PB_Editor_CompileCount
EndProcedure
; IDE Options = PureBasic 5.42 LTS (Windows - x64)
; ExecutableFormat = Shared dll
; CursorPosition = 9
; EnableThread
; Executable = test_call_dll.dll
; DisableDebugger
; HideErrorLog
; CurrentDirectory = D:\dev\PureBasic\temp\
; CompileSourceDirectory
; Compiler = PureBasic 5.42 LTS (Windows - x64)
; EnableCompileCount = 11
; EnableBuildCount = 11
; EnableExeConstant
; IncludeVersionInfo
; VersionField15 = VOS_NT
; VersionField16 = VFT_DLL
And here is the calling parent process:
Code: Select all
; ------------------------------------------------------------
; Program name: test01.pb
; Purpose: 64 bit exe to test a dll calling problem!
; ------------------------------------------------------------
EnableExplicit
Define result.i
Define cplibLibrary.i
Define libraryName.s
Define someNumber.i = #PB_Editor_CompileCount
Global NewList programList.s()
AddElement(programList())
programList() = "test01.pb"
OpenConsole()
libraryName = "test_call_dll.dll"
PrintN("filesize of " + libraryName + " is: " + Str(FileSize(libraryName)))
cplibLibrary = OpenLibrary(#PB_Any, libraryName)
If cplibLibrary <= 0
PrintN("!!!!!!!! Unable to open library: " + libraryName + " !!!!!!!!")
PrintN("cplibLibrary = " + Str(cplibLibrary))
Else
; prototype the procedure in the dll
Prototype test_dll_procedure(someNumber.i)
Define test_dll_procedure.test_dll_procedure = GetFunction(cplibLibrary, "test_dll_procedure")
; now call the dll procedure
result = test_dll_procedure(someNumber)
PrintN("test_dll_procedure returned result = " + Str(result))
EndIf
CloseConsole()
End
; IDE Options = PureBasic 5.42 LTS (Windows - x64)
; ExecutableFormat = Console
; CursorPosition = 12
; Executable = test01.exe
; CurrentDirectory = D:\dev\PureBasic\temp\
; CompileSourceDirectory
; EnableCompileCount = 9
; EnableBuildCount = 9
; EnableExeConstant
Please note that I have not yet updated my Windows 7 development machine. I prefer to do a full backup before loading windows updates.
Re: Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 3:49 pm
by Lunasole
I remember some note from PB docs
Code: Select all
- The declaration of arrays, lists or map with Dim, NewList or NewMap must always be done inside the procedure AttachProcess.
Don't know why it has to be done this way (can someone explain?), in my DLLs I ignored this (also even not declaring all those AttachProcess ()

) and they working fine anyway. But maybe in your case it matters.
Also your examples seems working fine.
Re: Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 3:52 pm
by skywalk
Help and my PB DLL Notes wrote:
; All arrays, linked-lists or maps with Dim, NewList or NewMap must be done in Procedure AttachProcess()!
; No program code outside Procedures, except declaration of variables or structures.
; DirectX initialization routines cannot be written in Procedure AttachProcess().
; Only Global strings can be returned from the DLL.
; Not sure where DataSections are handled, but no crashes so far.
Re: Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 4:12 pm
by RichAlgeni
It used to work on Windows!
The issue I am having is that I wanted to use the same include for mainline routines and dll's, for consistency purposes. I used the list to keep track of programs included into the parent process, along with their version numbers. I then can write out that list inside an onerror clause if needed.
I am able to append a string, but I wonder how much longer that will last?
Re: Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 4:23 pm
by skywalk
I use:
CompilerIf #ThisIsDLL
AttachProcess()
CompilerElse
ThisLib_AttachProcess()
CompilerEndIf
Re: Warning! Windows Server DLL Issue
Posted: Mon Mar 07, 2016 5:04 pm
by RichAlgeni
skywalk wrote:I use:
CompilerIf #ThisIsDLL
AttachProcess()
CompilerElse
ThisLib_AttachProcess()
CompilerEndIf
Great idea!
I had implemented an initialize process in most of my includes, so I think I will just place the code in there, and not have to worry about it.
Re: Warning! Windows Server DLL Issue
Posted: Tue Mar 08, 2016 7:23 pm
by PMV
Lunasole wrote:I remember some note from PB docs
Code: Select all
- The declaration of arrays, lists or map with Dim, NewList or NewMap must always be done inside the procedure AttachProcess.
Don't know why it has to be done this way (can someone explain?), in my DLLs I ignored this (also even not declaring all those AttachProcess ()

) and they working fine anyway. But maybe in your case it matters.
Also your examples seems working fine.
Until the same nightmare as RichAlgeni had it.
DLLs are just libraries with only procedures. So code outside of a procedure is forbidden.
Complexe datastructures like array, map or linked list need a little bit more to set up.
If it works now, you will just have a fun time ahead of you.

Thats why AttachProcess() is the way to go as already stated.
MFG PMV
Re: Warning! Windows Server DLL Issue
Posted: Tue Mar 08, 2016 7:42 pm
by RichAlgeni
PMV wrote:Thats why AttachProcess() is the way to go as already stated.
Agreed 100% MFG PMV! I have now created an initialization procedure for all of my PureBasic include type program, and have just completed adding a call to each initialization procedure into
AttachProcess().
It was stupid of me to blindly assume that
AddElecment() would work there!
Re: Warning! Windows Server DLL Issue
Posted: Wed Mar 09, 2016 11:44 pm
by Lunasole
PMV wrote:
Until the same nightmare as RichAlgeni had it.
DLLs are just libraries with only procedures. So code outside of a procedure is forbidden.
Complexe datastructures like array, map or linked list need a little bit more to set up.
If it works now, you will just have a fun time ahead of you.

Thats why AttachProcess() is the way to go as already stated.
MFG PMV
Well I'm using map in one dll declared this way;
A lot of data this map contains, but it is modified only from procedures, and DLL is executed in separated thread. For month this still works stable without AttachProcess() even being declared.
So until I got some "fun time" I won't do any extra movement anyway, hah.
Re: Warning! Windows Server DLL Issue
Posted: Thu Mar 10, 2016 1:53 am
by RichAlgeni
Declaring the variable is fine. My issue was that I was using AddElement(), but not in a procedure. That was the statement that was creating the fatal error condition.