COM dll called from PHP doesn't empty variables - iis

the problem I'm having started to appear lately and it doesn't appear everywhere.
The front end (html/js) calls PHP pages. PHP in turn calls functions from a COM dll (vb6). The COM dll does use some lower level C++ .dlls in turns, though not sure this information is relevant.
Now, lately (this did not happen before), in one specific COM dll function, let's call it BringClients(), sometimes (apparently some user concurrency happening - race condition?) a global variable let's say ClientName which is used within BringClients() is not empty when the function is called, but instead it holds a value, which is set on function UpdateClients() when this function is called in a completely different instance of the COM dll, by a completely different user.
I don't know why this is happening. Aren't all COM dll variables empty when the .dll is initialized? I worked around it by manually emptying the variable on each initilization of the .dll, but should this even be happening? I haven't noticed a similar issue on other functions.
The OS is Windows server with IIS.

I don't know how PHP interacts with COM components, but my guess is you don't really initialize the DLL, you create objects. And your COM library is apartment-threaded, so you will get an isolated set of variables per thread.
But what happens if IIS uses the same thread later (from a pool) based upon whatever scheduling it uses to balance requests? Then any global/public module-level data variables will still be there.
So yes, if you need to ensure that those variables are not re-used you are going to have to clear them or re-architect to remove all globals.

Related

RPG program error: Error MCH3601 was detected in file

We have been facing a very strange issue with one of our RPGLE programs that bombs intermittently with the subjected error.
This happens specifically at a line where a write operation is performed to a subfile record format. I have debugged and checked all the values assigned to variables during runtime and could not find absolutely no issues. As per the https://www.ibm.com/support/pages/node/644069 IBM page, I can only assume that this might be related to the parameter definitions of the programs called within the RPG. But I have checked the parameters of each and every prototyped program call and everything seems to be in sync.
Can some one please guide on the direction to go to find out the root cause of this problem?
But I have checked the parameters of each and every prototyped program
call
Assuming you're using prototypes properly, ie. there is one prototype defined in a separate source member and it is /INCLUDE into BOTH the caller and the callee...
Then prototype calls aren't the problem, as long as you're properly handling any *OMIT and *NOPASS parameters.
Look at any old style CALL or CALLB calls and anyplace you're not using prototypes properly...meaning there's a explicit PR coded in both caller & callee.
Note that you it's not just old-style calls made by the program that bombs, it's calls made anywhere down the call chain.
And if the program is repeatedly called with LR=*OFF or without reclaiming resources, then it could be any old style calls up the call chain also.
Lastly, old style calls include any made by CL or CLLE programs.
Good luck!

Synchronize () DLL freezes without errors and crashes

I built a modular program consisting of several programs (exe), and in some cases these modules are also in DLL. There are about 6 modules.
All of these modules used functions of a Thread. This thread does not use visual components, what it does is basically analyze huge files (> 1GB).
To improve the efficiency and organization, extract all the code relating to this file analysis, which is used by each of the modules. This facilitates updating and find error.
The threads worked normally before, no code change, except as necessary to adapt them to the DLL project.
Now, when I run the procedures of Thread, everything functions normally except the synchronize () method, which freezes without making errors or lock the main program.
The synchronize () method is used because the threads are created entirely within the DLL. Therefore, the main program is called a procedure DLL, which creates and runs the thread, without any intervention by the main program.
For this procedure are passed several parameters, one of them is a type "pointer to procedure" ^procedure, who is using it as an event, fired by the thread through the synchronize () periodically, ensuring that during the performance, which lasted more than one hour in most sometimes, if track progress, see errors errors among others.
I searched on google but did not find information except someone saying that possibly the synchronize () method is waiting for the main process that is not responding for unknown reasons.
Note: The main program and the window does not lock or freeze; only the thread that does not call / run procedure provided to synchronize (); I confirmed it!
Added
Nota2: I want to avoid as much use PostMessage () or similar, because it forces me to include LCL, which makes the DLL file up from the current 300K to 2MB (in release mode). Apart from that there are reports that its operation is not good as expected.
That is because you have two complete instances of everything (RTL,LCL etc). One set in the DLL, one set in the EXE. Both code and data.
You are probably calling the synchronize of the DLL, which schedules it for the LCL loop in the DLL which does nothing, since all work is done in the EXE.
This will be very hard to fix, basically you need packages for this. Partially also because the thread involvement will further complicate it because of threadvariables (Thread local storage) that is set up potentially differently for DLL and EXE threads.
For this one needs packages which is only in its initial stages and solves this by having only one copy of everything. See the link for a deeper treatise.

identifier is undefined in EXE if new'd in DLL and exported

I am newing a heap object in a regular DLL. I export it properly with __declspec(dllexport) and import it in the EXE with __declspec(dllimport) linkage. As long as I am in the DLL the object is defined properly, but when executing/debugging in the EXE, the object is undefined. What am I missing? Name mangling? Should extern "C" demangling help?
Further explanation:
#Colin Robertson My problem stems from the prototype using extension DLLs whose code is integrated with the EXE upon compile. I knew my app would need to access objects directly in the DLL from the EXE which is okay in windows extension DLLs because of the code integration. But the prototype turned out to be a memory hog as my app creates many DLLs during execution, each of which got integrated, dynamically I might add, into the running executable. Therefore, the production code had to use the regular DLL which has automatic reference counting (dllmain etc) as long as it isn’t statically linked. Which brings me to my current problem of how do I access the DLL object from within the EXE?
As such, the discussion in your links regarding the passing of allocator is not relevant. Point 60 (60. Avoid allocating and deallocating memory in different modules.) in Sutter and Alexandrescu's book does not apply since the EXE is not responsible for object lifecyle. Also, since I am using shared libraries, the following is true: “Specifically, if you use the Dll runtime option, then a single dll - msvcrtxx.dll - manages a single freestore that is shared between all dll's, and the exe, that are linked against that dll.” (see StackOverflow’s “Who allocates heap to my DLL?” whose thread was closed by poke, Linus Kleen, mauris, Cody Gray, miku for some reason). My code does not mix the allocation/deallocation responsibilities of the DLL with the usage requests of the EXE.
I think the problem lies in the fact that in a regular DLL, using a pointer to an object in another module’s allocated heap running in a different thread with its own message pump is disastrous and is censured by the compiler. This is as it should be.
But my problem is still legitimate.
I see two ways windows solves such a situation. One is the Send/PostMessage call which posts messages on other thread queues and the other is COM marshalling. For the former I would have a problem with the return value. Since what I am doing is basically a remote procedure call, my EXE wants results back from the DLL, and SendMessage only returns an HRESULT. As for the latter, this is exactly what COM does when it marshals a pointer in an Apartment threaded app (see “Single-Threaded Apartments” in MSDN). COM is designed to let you pass pointers between threads, or even processes. There might be a third C++ way which is to use the Pimpl idiom (see http://www.c2.com/cgi/wiki?PimplIdiom), but this method is a lot more work and has drawbacks. Thanks to MVP Scott McPhillips for this suggestion.
Does anyone have advice or experience on which way to proceed?
Don't do that. This is item 60 in Sutter and Alexandrescu's C++ Coding Standards book, which I highly recommend. Separate modules may use their own versions of the run time library, including the basic allocation routines. Things allocated on one module's heap may be inaccessible from another module, or have different conventions for allocating and freeing them. The name mangling conventions can be different, but that's the least of your worries. Here's another StackOverflow question that has more detailed answers for why this is a bad idea, and what to do instead: Is it bad practice to allocate memory in a DLL and give a pointer to it to a client app?

Creating a new "internal" process?

I'm writing a DLL (in Visual C++) and I recently decided that I need to move stuff that currently happens in threads into their own process. This is because I want to support multiple instances of the DLL being loaded and running. However, they all need to access the same group of resources (i/o buffers to a COM port) that needs to be autonomously monitored as long as there is at least one instance of the DLL running.
It seems I need to use CreateProcess(), but I'm unclear on how I should use the lpApplicationName argument. In the examples I've seen, the name of an existing program gets passed, but that isn't what I imagine I need to do. I expected to be able to start a process by specifying a function, much like with CreateThread(). The process doesn't need to be compiled and output as its own executable, does it? It definitely shouldn't be used by anything other than my DLL. Thanks.
EDIT: Okay, so if all CreateProcess() can do is start a pre-existing program, how can I get this to work? If the following happens:
Process loads the DLL
DLL starts port monitoring threads
Second process loads the DLL
Second DLL establishes some IPC to access the same data as the first DLL
First DLL is about to exit, and terminates the monitoring threads
Second DLL starts its own monitoring threads and continues
Doing 5 and 6 seems (especially with my implementation) like a clunky way of doing things, rather than just have behavior that I never have to terminate and restart.
EDIT: The more I think about this, the more I like the idea of making a separate executable, but if anyone think of a more "elegant" method, I'd still like to know.
You can't do that. On *nix you could fork can then call whatever function you want, but CreateProcess doesn't work that way. The only thing CreateProcess can do is launch a new process with execution starting at the entry point of an on-disk executable.

Synchronize() hangs up the thread

I'm writing a dll library in Delphi with multiple threads created by it. Let me describe the problem step by step. I'm sorry for a lengthy description in advance :-(.
Let's forget about the library for a while. I created a windows application that is going to present views from several cameras. I created a window which is meant to show the view from a single camera and it contains a TImage control. There is a thread (a TThread descendant) that downloads the current image from the camera every couple of milliseconds and assigns it to the TImage control of that window (using the Synchronize() method). The application creates several instances of that window on startup (with a separate thread for each of them), so you can see the live view from several cameras at once. What's more, all those viewing windows are parented by the main application window, so they appear within it.
Everything worked fine until I decided to put those two windows into a dll library. I just found it necessary for some reasons, but they are not important now. So I created a new dll library, added the existing main window and the camera-view window to the project and exported a function that creates and returns an instance of the main window. When the main window is created, it creates several camera-view windows, making itself their parent.
Then, for testing purposes, I created an app that imports the above mentioned dll function from the library and calls it at startup to get an instance of the main window; then just shows it on the screen (in a non-modal state).
When I started the app it came out that I couldn't get a single image from any camera then. When I debugged it, I noticed that when the thread calls the Synchronize() method, it hangs forever. It didn't happen before putting both those windows into a dll.
And this is my problem. To be honest, this is my first approach to libraries I have had to get through many other problems so far. You might wonder why I use windows instead of frames... So whenever I created an instance of a TFrame in a dll, I would get an exception saying "the control xxx does not have a parent window". I did not know what to do about that so I used windows instead :-(.
Could you please tell me what to do with the synchronization problem? The main thread does not seem to be blocked in any way when the application is started for it accepts clicking buttons etc. What is the problem then?
Please, help!
Thank you in advance!!
When you call TThread.Synchronize the thread and method pointer are added to a global SyncList: TList in Classes.pas. In the main exe's TApplication.Idle routine calls CheckSynchronize, which checks the SyncList, but it's going to check the version in the exe instead of the one in the DLL. End result, your synchronized methods are never called.
The easiest fix would be to switch from DLLs to packages, which would eliminate the duplicate SyncList.
Another approach would be to override the exe's Application.OnIdle callback, and call your DLL's CheckSynchronize manually. You would need some help from the application for that though, since your DLL will have an Application object too, and that one won't work.
It's a bad idea to use Synchronize, because it tends to lead to race conditions like this. I don't know what's going on specifically in your code--it's hard to tell without seeing any code--but this sort of issue is pretty common actually.
Inter-thread communication is better done with a queue. If you've got the latest version, Delphi XE, there's a TThreadedQueue<T> class in Generics.Collections that's ideal for this sort of thing. Pass 0 to the PopTimeout param in the constructor, have your camera threads push images, and have your main thread poll the queues with the third PopItem overload, like so:
var
CurrentItem: TImage;
begin
if ThreadQueue.PopItem(CurrentItem) = wrSignaled then
UpdateImage(CurrentItem); //or however you do it
end;
(If there's nothing in the queue, PopItem will return wrTimeout instead.)
If you don't have Delphi XE, you'll need to build your own threadsafe queue, or find one from a third party source, such as Primoz Gabrielcic's OmniThreadLibrary.
I found two ways to solve Synchronize() hanging up the thread (in Delphi 7):
Place a TTimer on the DLL form and have its OnTimer event call CheckSynchronize();
procedure TPluginForm.Timer1Timer(Sender: TObject);
begin
CheckSynchronize;
end;
Add this module to the uses section of the DLL form

Resources