I am writing a piece of code whereby I am to iterate through the list of modules loaded by the System process (PID : 4). The following is the code I am using to achieve it.
Process process = Process.GetProcessById(4);
foreach (ProcessModule pMod in process.Modules)
{
Console.Write(pMod.FileName + " ");
}
Console.WriteLine();
This code is throwing an error of System.ComponentModel.Win32Exception, whenever it is trying to evaluate the list of Modules. In effect, any property read or method call is throwing the same error. Any other process is working fine and it is able to list all the modules correctly. Could anyone shed light on what might be causing this behavior.
The System "process" (with PID 4 on Windows machines) is actually not a process at all, it denotes a group of processes that have SYSTEM integrity.
Try to work with a real process PID (for instance, run Internet Explorer, and use it's PID) instead, see if you`ll get the exception.
The system process is not a real user mode process, it is the Windows kernel (for want of a better description). Therefore it cannot be examined as if it were a normal process.
Related
This code runs as expected on a large number of machines. However on one particular machine, the call to WaitForExit() seems to be ignored, and in fact marks the process as exited.
static void Main(string[] args)
{
Process proc = Process.Start("notepad.exe");
Console.WriteLine(proc.HasExited); //Always False
proc.WaitForExit(); //Blocks on all but one machines
Console.WriteLine(proc.HasExited); //**See comment below
Console.ReadLine();
}
Note that unlike a similar question on SO, the process being called is notepad.exe (for testing reasons), so it is unlikely the fault lies with it - i.e. it is not spawning a second sub-process and closing. Even so, it would not explain why it works on all the other machines.
On the problem machine, the second call to Console.WriteLine(proc.HasExited)) returns true even though notepad is still clearly open, both on the screen and in the task manager.
The machine is running Windows 7 and .NET 4.0.
My question is; what conditions on that particular machine could be causing this? What should I be checking?
Edit - Things I've tried so far / Updates / Possibly relevant info:
Reinstalled .NET.
Closed any processes I don't know in task manager.
Windows has not yet been activated on this machine.
Following advice in the comments, I tried getting the 'existing' process Id using GetProcessesByName but that simply returns an empty array on the problem machine. Therefore, it's hard to say the problem is even with WaitForExit, as the process is not returned by calling GetProcessesByName even before calling WaitForExit.
On the problem machine, the resulting notepad process's ParentID is the ID of the notepad process the code manually starts, or in other words, notepad is spawning a child process and terminating itself.
The problem is that by default Process.StartInfo.UseShellExecute is set to true. With this variable set to true, rather than starting the process yourself, you are asking the shell to start it for you. That can be quite useful- it allows you to do things like "execute" an HTML file (the shell will use the appropriate default application).
Its not so good when you want to track the application after executing it (as you found), because the launching application can sometimes get confused about which instance it should be tracking.
The inner details here of why this happens are probably beyond my capabilities to answer- I do know that when UseShellExecute == true, the framework uses the ShellExecuteEx Windows API, and when it UseShellExecute == false, it uses CreateProcessWithLogonW, but why one leads to trackable processes and the other doesn't I don't know, as they both seem to return the process ID.
EDIT: After a little digging:
This question pointed me to the SEE_MASK_NOCLOSEPROCESS flag, which does indeed seem to be set when using ShellExecute. The documentation for the mask value states:
In some cases, such as when execution is satisfied through a DDE
conversation, no handle will be returned. The calling application is
responsible for closing the handle when it is no longer needed.
So it does suggest that returning the process handle is unreliable. I still have not gotten deep enough to know which particular edge case you might be hitting here though.
A cause could be a virus that replaced notepad.exe to hide itself.
If executed, it spawns notepad and exits (just a guess).
try this code:
var process = Process.Start("notepad.exe");
var process2 = Process.GetProcessById(process.Id);
while (!process2.HasExited)
{
Thread.Sleep(1000);
try
{
process2 = Process.GetProcessById(process.Id);
}
catch (ArgumentException)
{
break;
}
}
MessageBox.Show("done");
After Process.Start() check the process id of notepad.exe with the taskmanager and verify it is the same as process.Id;
Oh, and you really should use the full path to notepad.exe
var notepad = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.Windows), "notepad.exe");
Process.Start(notepad);
I'm attempting to get the module name for each thread in a process. Process explorer shows the name of the module associated with each thread no problem. I can enumerate all modules and all threads in my current process with no problems, and get data related to them. My current method of deducing the associated module is the following:
if(module.BaseAddress < thread.StartAddress && (module.BaseAddress + module.BaseMemorySize) > thread.StartAddress)
{
// this is our module ;)
}
Unfortunately, that doesn't seem to be a concrete way of doing it. The xfire_toucan.dll module shows in procexp fine:
1972 : xfire_toucan.dll!ToucanSendGamestatsConsoleLine_V1+0x80
In the list of modules, it shows with a base addr of 0x10000000 and a size of 0x26b000, giving us a max memory addr of 0x1026b000. However, the associated thread start address is 0x775e2ca0, which is part of an allocated block of memory in the process outside the module's main memory range.
Any idea how to get the module like ProcExp does?
I know C and C#, so either is fine, but my project is C# so that's preferred :]
Process explorer isn't showing you the module associated with each thread. Windows does not maintain this information. It's showing you the symbol name for the thread's entry point. This will usually (but not always) be a function in the module that started the thread. If you want to retrieve this sort of information in your program, you can use the debug help API. They're probably using the StackWalk64 function to retrieve the entry point name.
I am using Interop.WinHttp and when I run the application it gives me this exception on a line of code that is using Interop.WinHttp like this:
System.OutOfMemoryException: Retrieving the COM class factory for component with CLSID {91E2EAD3-AB7E-4D5C-88DE-F7FA382172BC} failed due to the following error: 8007000e.
WinHttp.WinHttpRequest oHTTP = new WinHttp.WinHttpRequest();
do you have any troubleshooting ideas to solve this?
It is a Windows error. The mapping to OOM isn't the greatest idea, the description for error code 14 is "Not enough storage is available to complete this operation". The most typical cause is exceeding a quota imposed by Windows on a process. Like opening too many sockets or using too much memory from the kernel pool.
You'll need to find out what resource is being consumed. One place to start is Taskmgr.exe, Processes tab. View + Select Columns and tick Handles, User32 Objects and GDI Objects. Handles being the likely one in this case. Correlate the increase of this value with the execution of your code.
I am working on a tool that monitors a number of applications and ensures they are always running and in a clean state. Some of these applications have unhandled exceptions which do occur periodically and present the 'send crash report' window. I do not have the source code to these applications.
Is there any mechanism I could use to catch the exceptions, or simply identify their exception type, as well as identify the application's main executable file that threw the exception.
I'm not trying to do anything crazy like catch and handle it on the applications behalf, I'm simply trying to capture the exception type, log it and then restart the application.
Trapping unhandled exceptions requires calling SetUnhandledExceptionFilter() in the process. That's going to be difficult to do if you don't have source code, although it is technically possible by injecting a DLL into the process. This however cannot be done with managed code, you can't get the CLR initialized properly.
The default unhandled exception handler that Windows installs will always run WerFault.exe, the Windows Error Reporting tool. That can be turned off but that's a system setting. Expecting your user or admin to do this is not realistic. Only after WER runs will the JIT debugger get a shot at it.
I recommend a simpler approach, one that's also much more selective. Use the Process class to get the program you're interested in protecting started. When the Exited event fires, use the ExitCode property to find out how it terminated. Any negative value is a sure sign that the process died on an unhandled exception, the exit code matches the exception code. You can use the EventLog class to read the event message that WER writes to the Windows event log. And you can restart it the same way you got it started.
Without modifying the source of the application or injecting a DLL into the process I do not believe this is possible in a reliable fashion. What you're attempting to do is inspect type information across a process boundary. This is not easy to achieve for a number of reasons
Getting the name of the exception implies executing code in the target process. The name can be generated a number of ways (.ToString, or .GetType().Name) but all involve executing some method
You want to do this after the application has already crashed and hence may be in a very bad state. Consider trying to execute code if memory was corrupted (perhaps even corrupting the in memory definitions of the type).
The crash could occur in native code and not involve any managed data
If you want to monitor application crashes system wide, you can register yourself as a just-in-time debugger. You can edit the registry to specify which debugger to run when an application crashes. The example they give is Doctor Watson, but it could be your application instead.
I need to run tests on system recoverability which includes suddenly crashing a system without warning ("hard crash", no shutdown workaround).
I'm looking for something as close as possible to a serious hardware error that just fully crashes the system (blue screen HALT or worse, e.g .sudden reboot similar to non-recoverable memory/cpu errors).
How could I do something like this in C# (probably unmanaged code?)?
I always find flipping the power switch (on the wall socket) works perfectly for this solution - especially when I only meant to turn the monitor off.
If you need to do it from the keyboard, check here for a way to generate a BSOD.
EDIT: a quick google suggests there are 3 ways:
write a device driver and dereference a null pointer
do the keyboard shortcut described above
run windbg in kernel mode and type .crash at the prompt.
Find and kill the process running csrss.exe. That will take care of it.
I guess that the easiest way to do it, espacially if you want to build it into some kind of automated test (which I guess that you will when you say that, "How could I do something like this in C#") is to create a new AppDomain.
I.e. your automated test will create a new AppDomain, and then startup your application inside the new AppDomain. Your automated test can then unload the AppDomain. That will completely abort the application. It will be close to 100% identical to what happens during hardware crash, so it will allow you to test your recovery code. I don't think that it will leave your file system corrupt however (thus not 100% identical)
Note that if you are not used to working with multiple AppDomains, there are a few things to be aware of. E.g. when you access an object in another AppDomain, the object will be serialized across the AppDomain boundary, except if it inherits from MarshalByRefObject.
I have a similar situation, where we are testing exactly the same (recovery from an unexpected crash). Here, the code that launches a new AppDomain creates a "bootstrapper" object inside the new AppDomain. This bootstrapper is a MarshalByRefObject specialization and has the responsibility of executing application startup logic.
There's a way to manually BSOD a machine. A tutorial is available here. After setting up the necessary registry entries you can crash the machine by pressing Right Ctrl and Scroll Lock.
I was trying something new today and totally crashed my system successfully... Check out my code..
using System;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
Process[] processess = Process.GetProcesses();//Get all the process in your system
foreach (var process in processess)
{
try
{
Console.WriteLine(process.ProcessName);
process.PriorityClass = ProcessPriorityClass.BelowNormal; //sets all the process to below normal priority
process.Kill();
}
catch (Exception E)
{
Console.WriteLine(E.Message + " :: [ " + process.ProcessName + " ] Could not be killed");
}
}
}
};