Unmanaged thread running Managed Code - c#

I made a software that loads external module made by clients.
This software is supposed to be HA (High availability) meaning it CAN'T be allowed to crash.
For that purpose, I created a class which creates a thread, run the client module function in it, and returns. The class allows a certain time to execute the function, and if it takes too long, it kills the thread. Like this, if the client screwed up his module by having an infinite loop or whatever in his code, the rest of the system doesn't freeze.
Now, the question I have...If the thread running the function is created in unmanaged code (C++) and the module function running in it is managed code, what kind of problem could I have by killing the thread?
Thanks,

In general, it's unsafe to kill a thread in a running process; see the warnings and notes in TerminateThread.
If I were doing such an app, I would be inclined to investigate ways to host the 3rd party module within a separate process with a well-defined communication interface; eg: inside a COM+ application. This would allow you to kill the entire process if it gets "out of control", without affecting the stability of the "host" process.

Related

Executing code in main thread via dll injection

I need to inject a dll into the main thread of a process (otherwise my process will crash)
How would I go about doing this? My dll is in C++ obviously, my injection method though uses C# and CreateRemoteThread.
I've tried using std::thread(func) but that didn't work (of course it probably wouldn't since it most likely creates a new thread)
I don't know if this is a problem for my DLL or my injector, so all help and attempts to help is appreciated.
Your DllMain will run in the context of every thread... figure out which is the main thread.
Since you can't do much while the loader lock is held, create a callback with thread affinity (for example using SetTimer) and do all the work from that callback.
You can create the target process suspended and use CreateRemoteThread() for injection, but mind the following limitations:
You should copy the thread main routine for the remote thread to the address space of the target process.
This code cannot contain any external references (e.g. CRTL or direct WinApi calls). I would usually limit this code to loading of the DLL and either executing function from it, or relying on the DllMain to do the job you need. In order to call LoadLibrary and GetProcAddress methods, I obtain their addresses and copy structure containing this information to the target process and pass the address of the remote structure as an argument for the thread main routine in CreateRemoteThread(). You can use VirtualAllocEx() to allocate memory in the remote process,
Remote thread in this situation will be executed before main thread, including process and some Win32/64 initialization. Therefore, not every Win32 API is safe to call in this condition.
You can read more here: http://blogs.microsoft.co.il/pavely/2017/03/14/injecting-a-dll-without-a-remote-thread/

How to handle blocking synchronous external DLL methods

Recently I worked with an external dll library where I have no influence on it.
Under some special circumstances, a method of this third party dll is blocking and never returning.
I tried to work around this issue by executing this method in a new AppDomain. After a custom timeout, I wanted to Unload the AppDomain and kill all this crap ;)
Unfortunately, it does not work - as someone would expect.
After some time it throws CannotUnloadAppDomainException since the blocking method does not allow aborting the thread gracefully.
I depend on using this library and it does not seem that there will be an update soon.
So can I work around this issue, even if it's not best practice?
Any bad hack appreciated :)
An AppDomain cannot typically solve that problem, it's only good to throw away the state of your program. The real issue is that your thread is stuck. In cases like these, calling Thread.Abort() is unlikely to work, it will just get stuck as well. A thread can only be aborted if it is a "alertable wait state", blocking on a CLR synchronization object. Or executing managed code. In a state that the CLR knows how to safely clean up. Most 3rd party code falls over like this when executing unmanaged code, no way to ever clean that up in a safe way. A decisive hint that this is the case is AppDomain.Unload failing to get the job done, it can only unload the AppDomain when it can abort the threads that are executing code in the domain.
The only good alternative is to run that code in a separate process. Which you can kill with Process.Kill(). Windows do the cleanup. You'd use a .NET interop mechanism to talk to that code. Like named pipes, sockets, remoting or WCF. Plus the considerable hassle of having to write the code that can detect the timeout, kills the process, starts it back up and recovers internal state since you now restart with an uninitialized instance of that 3rd party code.
Do not forget about the real fix. Create a small repro project that reproduces the problem. When it hangs, create a minidump of the process. Send both to the 3rd party support group.
after reading this (scroll down the end to Blocking Issues) I think your only solution is to run the method in a different process - this might involve quite a bit of refactoring and/or a 'host' project (eg Console application) that loads the method in question and makes it easy to call (eg reading args from command line) when launching the new process using the Process class
You can always use background worker, no need to create a new appdomain. This will ensure that you have complete control over the execution of the thread.
However, there is no way to ensure that you can gracefully abort the thread. As the dll is unmanaged, chances are there that it may cause memory leaks. However, spawning a new thread will ensure that your application does not crash when the Dll does not respond.

Does the System.Diagnostics.Process.Exited Event Always Fire?

I have an application that I am writting that communicates with a third-party program through a COM connection. I was tasked to strengthen the resilency of our application, in order to do that I wait until the third-party application is ready. I do this by waiting until the return value on a method that returns true only when the third-party application has been fully loaded.
In an effort to avoid the condition where the application crashes during this procedure, and my application just sits there waiting throwing COM errors( caught of course ) I was wondering if the Exited event on the Process itself, is guaranteed to always happen?
I am more then willing to provide additional details when its possible. I am also for the time being limited to .NET Framework 2.0 with this current build.
It depends on the sort of crash - some crashes leave the "process" in memory (for example just stuck in some never-ending loop OR that COM object opened some modal error dialog and waits for user)... these cases are not covered by any method mentioned in your description...
In my experience to be really resilient you need a combination:
hook the Exited event (if you started the application via Process) OR find the process ID and monitor that
catch any exceptions from that COM object
implement a timeout + abort logic for calls to that COM object/application
"monitor" the COM object/app
I usually start a separate thread before calling such a COM object... that thread monitors the COM object/application for example if it open any window it is not supposed or memory consumption goes through the roof when it is not supposed to etc. - the things monitored and the reaction to each of them is rather specific to that COM object/application...

Interface freezes in multi-threaded c# application

I have a c# .NET multi-threaded application that is freezing the interface. What is unusual about this is that the interface does not freeze unless I let the system sit idle long enough for the screen saver to start (which requires me to reenter my password to re-gain access to the system). When the interface becomes visible again (after I have successfully entered my password) the interface is locked up. As long as I don't let the screensaver start, then the interface does not lockup.
I should point out that I have two different executables that access the same dll and this problem is occurring no matter which application I use to access the DLL. This seems to imply that the problem is in the DLL as the two applications are completely different (C++/MFC) and (C#/.NET) apart from how they relate to the DLL.
Both exes perform similar steps in how they interact with the DLL. They make calls into the dll to setup the serial port communication, open a status window in the DLL, start a thread in the DLL to monitor the comm port, and then starts a thread in the main app that monitors a stack in the dll.
When data is obtained from the comm port by the thread in the DLL, it is parsed and its results are placed on the stack and then posted to the status window via a delegate. When the thread in the exe sees data in the stack, it outputs the data in the main window, also using a delegate.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal.
I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock.
This issue occurs both on my development machine and on a test machine.
I have tried completely removing the output of data to the status window inside the DLL, but that didn't make any difference.
I have been doing multi-threaded programming for years and never seen anything like this; so any advice would be greatly appreciated.
Thanks.
This is a problem that's commonly induced by the SystemEvents class when you have a non-standard way to initialize your user interface. Using threads, specifically. Start your program, Debug + Break All, Debug + Windows + Threads. If you see a thread named ".NET SystemEvents" then you're pretty much guaranteed to get this hang.
Some background: the SystemEvent class supports both console mode apps and GUI apps. For the latter, it should fire its event handlers on the UI thread. The very first time one of its events is subscribed, it creates a little invisible helper window to get the system notifications. It can do this two ways, either by creating the window on the calling thread or by starting up a helper thread. It makes the decision based on the value of Thread.GetApartmentState(). If it is STA then it can create the window on the calling thread and all event callbacks can be properly marshaled to that thread.
This goes wrong if the first window you create is not created on the UI thread. A splash screen for example. That window may contain controls that are interested in a system event like UserPreferenceChanged so they can properly repaint themselves. It now uses the helper thread and any event will be fired from that helper thread, not the UI thread. Poison to any window that runs on the UI thread. The session switch out of a locked workstation (including the screen saver) is for some mysterious reason very likely to cause deadlock. You may also see an occasional painting mishap, the less nasty result of using windows from the wrong thread.
Short from fixing the initialization order, a workaround is to put this in your Main() method, before any windows are created:
Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { };
The problem does appear to be related to the ActiveX control is was probably using incorrectly in a form. I switched to using the serial port library in .NET and have not been able to reproduce my problem. Thanks to everyone, especially Hans for their assistance.
I am having the same issue as my PC just hangs up when the screen saver kicks off or I lock my PC and monitor goes to sleep.
I am 95% sure that there are deadlocks appearing in my multithreaded app. Look and identify whether there are any deadlocks in your code.

Tracking - and correctly ending - native and managed threads in a C# - C++/CLI - C++ Windows forms application prior to exit

This is a follow-on from:
Debugging a Multithreaded C# - C++/CLI - C++ Solution in Visual Studio 2008: What are these threads?
Please excuse the format, I've just repeated some of the description of the application here:
I've inherited a project consisting of three levels of code. The lowest layer is native C++ that interacts with hardware. This is mature, stable and well-tested. The intermediate level code is C++/CLI, which interacts with top-level C# code that contains the UI elements and some additional functionality. This C# code is incomplete and was rushed in development: it crashes frequently and is not fit for purpose. My task is debug it and complete it.
I received some very helpful info from the last question I asked - but now there's more issues! My problem at the moment is that when I invoke Application.Exit() to shut down the UI and quit the application, an exception is thrown:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute
I understand that this is because I need to ensure that all of my threads are ended before I call Application.Exit() (or Application.ExitThread()). I've tried using MainForm.Close() as quick fix while I investigate further but it doesn't alleviate the problem.
I don't want to just called Thread.CurrentThread.Abort(), mainly because some of the threads originate in the C++ section of the code, via Boost::Thread, and I'm unsure exactly what resources I may leave in an undesirable state (a lot of the code consists of objects for interaction with hardware, such as a serial port - it's not been implemented via RAII so I'm rather cautious of brute forcing things).
What I'd like to be able to do is identify what threads are doing what, and gracefully end them prior to exiting the application. However, in VS 2008, the stack trace - with 'Show External Code' activated - only reveals
[Native to managed transition]
[Managed to native transition]
so I'm still having difficulty tracing the individual native threads and thus working out the best way to end them.
I tried using Allinea DDTLite, which seemed excellent - but I've had some issues with my VS installation and I had to disable the plug-ins, so it wasn't a solution.
To summarise: what is the most effective way to ensure that all threads - both managed and native - are correctly finished so that the UI and then the
the entire application can exit cleanly?
What I'd like to be able to do is identify what threads are doing what
You cannot make this work. There are ways to enumerate the threads in a process, like the managed Process.Threads property or the native Thread32First/Next but you don't get nearly enough info about the threads to know what they do. And most certainly not to shut them down cleanly. Further complicated by the .NET framework using threads for its own purposes, like the debugger thread and the finalizer thread and a smattering of threadpool threads.
You can kill these threads rudely with TerminateThread, albeit that killing the finalizer thread will crash the program immediately, but that's no different from rudely terminating the process with Environment.Exit(). With the caveat that nothing is cleaned-up nicely. Windows will clean up most of the shrapnel though.
This should not normally be a problem. You know what threads you started, there should also be a mechanism to ask them to shut down. That's normally done by signaling an event, something that's tested in thread's main loop. Waiting on the thread handle confirms that the thread indeed exited. After which you can close the windows.
But that's probably plumbing that's missing, you'll have to add it. If the current native C++ code has no mechanism to take care of thread shutdown then you've got a fairly big problem. I'll guess that maintaining this native C++ code is the real problem. You may have to hire a gun to get this done.

Categories