SetEventWinHook crashes WPF application with Stack Overflow - c#

I am running into a problem where my application is crashing a WPF application due to EventHooking. Below is simple code that I tried and was still able to recreate the crash. This is only when running against some sort of custom tree view that has a number of its nodes expanded.
{
...
_focusChangedHandler = OnFocusChanged;
_focusChangedGCHandle = GCHandle.Alloc(_focusChangedHandler);
_focusChangedHookId = User32.SetWinEventHook(User32.EVENT_OBJECT_FOCUS,
User32.EVENT_OBJECT_FOCUS, IntPtr.Zero, _focusChangedHandler,
0,0,User32.WINEVENT_OUTOFCONTEXT);
...
}
private void OnFocusChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd,
int idObject, int idChild, uint dwEventThread,
uint dwmsEventTime)
{
}
I also had the customer test this with an explicit new User32.WinEventDelegate(OnFocusChanged) and without the GCHandle.Alloc. As well as a combination of all those scenarios. This did NOT solve the problem
Does anybody have any idea why this might be happening?
*We did have a problem with this WPF application and creating memory/performance issues around virtualization being cancelled by IAccessible calls, however we have since removed those calls.
EDIT PER REQUEST
The only information I have on the third party is from an event log:
Faulting application name: THIRDPARTY.exe, version: x.y.z, time stamp: 0x4fb0d031
Faulting module name: clr.dll, version: 4.0.30319.296, time stamp: 0x50484aa9
Exception code: 0xc00000fd
Fault offset: 0x00001ac6
Faulting process id: 0x6f50
Faulting application start time: 0x01cdf9a521428158
Faulting application path: C:\Program Files (x86)\THIRDPARTYEXEPATH
Faulting module path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Report Id: d8e42ff6-6598-11e2-9614-441ea14b96e0
The Exception code is a stack overflow as far as my research tells me

Related

HMACSHA256 causes AccessViolationException when reused parallelly

Why there is nowhere written that HMACSHA256 can cause System.AccessViolationException when accessed parallelly? The AccessViolationException is super hard to investigate since it cannot be caught by regular try-catch (from .Net 6.0 it cannot be caught at all) and since it is usually thrown elsewhere than where it was caused.
Or even more concerning: why nowhere in documentation is written that (HMAC)SHA256 shall not be reused at all? See example of same strings being hashed differently.
Why I am asking:
Our newly written app was randomly crashing after minutes or hours. In the Windows Event Viewer we then found:
Faulting application name: XXXXX.exe, version: 1.0.0.0, time stamp: 0x62571213
Faulting module name: coreclr.dll, version: 6.0.522.21309, time stamp: 0x625708f4
Exception code: 0xc0000005
Exception code 0xc0000005 is the code of the AccessViolationException. It took days to determine what was causing the problem and we were rather lucky to identify it:
since we do a lot of optimization it seemed reasonable to cache the instance of HMACSHA256 and reuse it. Eventually it was accessed by two threads at once and caused the application to crash without any log message (there was only the error code in the Event Viewer, no stacktrace).
Code example producing System.AccessViolationException immediately:
var keyString = "abcdefghijklmnopqrstuvwxyz0123456789";
var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(keyString));
var parallelOptions = new ParallelOptions() { MaxDegreeOfParallelism = 4 };
static IEnumerable<string> EnumerateStrings()
{
while (true)
{
yield return "A short string";
yield return "Lorem ipsum dolor sit amet, consectetur adipiscing elit ...";
}
}
Parallel.ForEach(EnumerateStrings(),
parallelOptions,
theString => hmac.ComputeHash(Encoding.UTF8.GetBytes(theString)));
Disclaimer: I do not require an answer to this question. I just wish somebody has asked exactly this question somewhen before me - it could have given me some clue. I would probably spend less time hitting my head against the wall. Hope it will spare some other heads.

Getting error from window service with Exception code: 0xc0000005

We are getting error on server and our service is automatically stopped in the server.
Randomly application is crash in approx 1 hour with below Error as -
Faulting application name: Chubb.Studio.Event.Processor.exe, version:
0.0.0.0, time stamp: 0x5c0ab1b7 Faulting module name: KERNELBASE.dll, version: 6.3.9600.19425, time stamp: 0x5d26b6e9 Exception code:
0xc0000005 Fault offset: 0x0000000000001556 Faulting process id:
0x115c Faulting application start time: 0x01d5a35fd202f96d Faulting
application path:
E:\WindowsService\DevInt\Chubb.Studio.EventProcessor\Chubb.Studio.Event.Processor.exe
Faulting module path: C:\Windows\system32\KERNELBASE.dll Report Id:
762c15d4-0f5b-11ea-8120-005056a27597 Faulting package full name:
Faulting package-relative application ID:
Our Code is look like as -
protected override void OnStarted()
{
//IntializeEventsExecution();
Task task = Task.Factory.StartNew(() => IntializeEventsExecution());
base.OnStarted();
}
public void IntializeEventsExecution()
{
StartEvents();
}
public void StartEvents()
{
var eventList = GetEventTopics();
Parallel.ForEach(eventList,
new ParallelOptions { MaxDegreeOfParallelism = eventList.Count },
(item, state, index) =>
{
StartProcessingEvent(eventList[(int)index]);
});
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
public void StartProcessingEvent(EventTopic topic)
{
try
{
Task task = Task.Factory.StartNew(() => ExecuteProcessingEvent(topic));
task.Wait();
}
catch (Exception)
{
}
finally
{
new _processingDelegate(StartProcessingEvent).Invoke(topic);
}
}
As Klaus says in his comment, a STATUS_ACCESS-VIOLATION exception is caused by a process reading or writing memory that it doesn't own. Given this is C#, the most likely reason is either an incorrect use of P/Invoke or using unsafe code.
The best approach to debugging something vague like this is to isolate the issue by removing P/Invoke calls one by one until the exception doesn't happen. It's hard to be more precise because the exception may be triggered a long way from the cause (memory or stack corruption).
This SO answer gives a good list of the likely causes of an access violation in managed code.
Access violations in managed apps typically happen for one of these
reasons:
You P/Invoke a native API passing in a handle to a managed object and the native API uses that handle. If you get a collection and
compaction while the native API is running, the managed object may
move and the pointer becomes invalid.
You P/Invoke something with a buffer that is too small or smaller than the size you pass in and the API overruns a read or write
A pointer (IntPtr, etc) you pass to a P/Invoke call is invalid (-1 or 0) and the native isn't checking it before use
You P/Invoke a native call and the native code runs out of memory (usually virtual) and isn't checking for failed allocations and
reads/writes to an invalid address
You use a GCHandle that is not initialized or that somehow is pointing to an already finalized and collected object (so it's not
pointing to an object, it's pointing to an address where an object
used to be)
Your app uses a handle to something that got invalidated by a sleep/wake. This is more esoteric but certainly happens. For example,
if you're running an application off of a storage card, the entire app
isn't loaded into RAM. Pieces in use are demand-paged in for
execution. This is all well and good. Now if you power the device off,
the drivers all shut down. When you power back up, many devices simply
re-mount the storage devices. When your app needs to demand-page in
more program, it's no longer where it was and it dies. Similar
behavior can happen with databases on mounted stores. If you have an
open handle to the database, after a sleep/wake cycle the connection
handle may no longer be valid.

Thread.Abort in ASP.NET app causes w3wp.exe to crash

Please do not set duplicate flag on this qustion - it is not about "why ThreadAbortException occurs", it is about "why w3wp.exe process terminates after ThreadAbortException".
Let's say we have simple web application with following code sample:
protected void Page_Load(object sender, EventArgs e)
{
Response.Redirect("http://google.com");
}
Which by fact means something like (see Is Response.End() considered harmful?):
protected void Page_Load(object sender, EventArgs e)
{
...response write some data...
System.Threading.Thread.CurrentThread.Abort();
}
On my machine (Windows 10 Pro + IIS) this code leads to IIS pool process termination with error code 0x0 (redirect not performs). On other machines (which is NOT Windows 10) this code only generates ThreadAborted exception, but process continue working (redirect performs).
Can someone check this sample and explain what is going on?
UPDATE
Here some windows event logs related to this issue.
log #1
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/1/ROOT/AS
Process ID: 6700
Exception: System.Threading.ThreadAbortException
Message: Thread was being aborted.
StackTrace: at
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest
wr, HttpContext context) at
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr
rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData,
Int32 flags) at
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr
rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData,
Int32 flags)
log #2
Faulting application name: w3wp.exe, version: 10.0.10240.16384, time stamp: 0x559f3dad
Faulting module name: KERNELBASE.dll, version: 10.0.10240.16384, time stamp: 0x559f3b2a
Exception code: 0xe0434352
Fault offset: 0x000b3e28
Faulting process id: 0x1a2c
Faulting application start time: 0x01d0e4b1b3ed01cb
Faulting application path: C:\WINDOWS\SysWOW64\inetsrv\w3wp.exe
Faulting module path: C:\WINDOWS\SYSTEM32\KERNELBASE.dll
Report Id: 23b5298d-3b36-49c7-a294-de9c864b703f
Faulting package full name:
Faulting package-relative application ID:
I was able to reproduce the issue on Server 2008r2 with .NET 4.6 installed.
I suspect it was the same problem the rest of you are running into; ThreadAbortExceptions killing the application pool in the event log (though any unhandled exception would cause the issue in my case; but that may just be a global exception handler catching it and finishing with a Response.End or Redirect). The dump stacktrace also matches the one in Ian's answer.
There was a MS Connect ticket opened for the issue, and a recent KB hotfix resolves the issue for me.
Connect Article: https://connect.microsoft.com/VisualStudio/feedback/details/1605438/disabling-ryujit-breaks-asp-net
KB Hotfix:
https://support.microsoft.com/en-us/kb/3098786
So far I have the only one solution:
static class WebExtensions
{
public static void EndSafe(this HttpResponse response)
{
response.Flush();
response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
public static void RedirectSafe(this HttpResponse response, string url)
{
response.Redirect(url, false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
This is however forces me to ensure that there will be no code executed after it:
...some code
response.RedirectSafe(url);
return; //<-- important
...some more code
Pay attention, that only "return" is not enough in some cases (for example with recursive calls) and in some cases you may need to avoid using "return" (with try-finally constructions)
I ran into this exact same problem on Windows 8.1 today, after rebooting to install Windows Updates.
The problem was that I had manually disabled RyuJIT in the Registry, due to this issue, by adding the useLegacyJit DWORD and setting it to 1 (see Method #3). But one of the updates created the UseRyuJIT key in the same location and set it to 1 as well, and this apparently confused ASP.NET horribly.
The solution was to set useLegacyJit to 0 and issue an iisreset. After that, all is good in the world.
WinDbg's !clrstack showed the following frames when I debugged the w3wp.exe dump. Perhaps this will help others with the same error who are Googling for a solution:
000000ef9892be98 00007ffa0e2d1fea [HelperMethodFrame: 000000ef9892be98]
000000ef9892bf80 00007ff99d776588 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892df90 00007ff9fc172345 [FaultingExceptionFrame: 000000ef9892df90]
000000ef9892e490 00007ff99d7796c0 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
000000ef9892e520 00007ff99d777377 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892e700 00007ff99d77655a System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892e740 00007ff99d775c11 DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)
000000ef9892ef58 00007ff9fc100b4e [InlinedCallFrame: 000000ef9892ef58] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000ef9892ef58 00007ff99d78cc1b [InlinedCallFrame: 000000ef9892ef58] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000ef9892ef30 00007ff99d78cc1b DomainNeutralILStubClass.IL_STUB_PInvoke
000000ef9892f000 00007ff99d77756c System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892f1e0 00007ff99d77655a System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892f220 00007ff99d775c11 DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)
000000ef9892f418 00007ff9fc100da3 [ContextTransitionFrame: 000000ef9892f418]
I've been experiencing the same issue on Win7 SP1. Web app compiled targeting .net 4.5.2 and running on .net 4.6. And I haven't been messing with the useLegacyJit or useRyuJIT registry flags.
Turned out "Enable 32-Bit applications" was unnecessarily set to Enabled on my app domain. Disabling it fixed the problem.

Executing msbuild process through code gets exit code -1073741502

My application is executing MsBuild.exe using Process.Start(); running as another user. The process is running as a service. When executing the process instantly fails and returns an error code -1073741502.
I am executing my code as a service.
No matter what user, or permissions I grant this occurs (Even as Administrator).
The service user has both the Local Security Policy to Run as a service and Impersonate another user
No matter what my logging methods are not called. Does this means it's failing before it even starts?
Other executables have no problem executing in this manner.
When not executing my code as a service it executes successfully.
WTF is the negative error code 1073741502??(!!) Closest thing i've found is this.
Example code:
void Main(){
var startInfo = new ProcessStartInfo
{
FileName = path,
Arguments = args,
WorkingDirectory = workingPath,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
LoadUserProfile = true,
Domain = System.Environment.MachineName,
UserName = creds.Username,
Password = generateSecureString(creds.Password)
};
var process = Process.Start(startInfo);
process.OutputDataReceived += process_OutputDataReceived;
process.ErrorDataReceived += process_OutputDataReceived;
process.Exited += process_Exited;
process.EnableRaisingEvents = true;
process.WaitForExit();
}
internal void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
void process_Exited(object sender, EventArgs e)
{
var process = ((Process) sender);
Console.WriteLine("Process has finished execution, exit code '{0}'.", process.ExitCode);
}
private SecureString generateSecureString(string password)
{
var secure = new SecureString();
foreach (var c in password.ToCharArray())
{
secure.AppendChar(c);
}
return secure;
}
Any help would be really appreciated. Seems to be a permissions/local security policy issue, but without knowing more it feels like i've reached the "definition of insanity" point of my troubleshooting where i'm just repeating the same actions expecting a different result.
When investigating the Event logs I see the following exception (vague as hell):
Faulting application name: msbuild.exe, version: 12.0.31101.0, time stamp: 0x545443d5
Faulting module name: KERNELBASE.dll, version: 6.3.9600.17668, time stamp: 0x54c846bb
Exception code: 0xc0000142
Fault offset: 0x0009e052
Faulting process id: 0x3e8
Faulting application start time: 0x01d065cdac34cc77
Faulting application path: C:\Program Files (x86)\MSBuild\12.0\Bin\msbuild.exe
Faulting module path: KERNELBASE.dll
Report Id: ecce8b9d-d1c0-11e4-80d7-00155d611ee6
Faulting package full name:
Faulting package-relative application ID:
According to this thread ( Why is this process crashing as soon as it is launched? ), starting a process from a service may result in the native CreateProcessWithLogonW API call which seems to be not working from a service.
I just found this thread because I think I'm facing a similar issue but with the powershell start-process commandlet running in a service (which probably make use of CreateProcessWithLogonW internally.

how to get more information on an exception

I created a solution in visual studio 2008 on windows 7, 64 bit.
It works.
When I move it onto another machine, also win 7, 64 bit, it crashed with almost no information.
The original issue was this:
call was rejected by callee
I then implemented this solution:
how to properly GetTypeFromProgID for visual studio 2008
However, now my issue is that when I run the executable on a different machine, the program is crashing immediately with the following information:
Description:
Stopped working
Problem signature:
Problem Event Name: APPCRASH
Application Name: EmailSalesVolumeSolution.exe
Application Version: 1.0.0.0
Application Timestamp: 508064dd
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.1.7601.17932
Fault Module Timestamp: 503285c2
Exception Code: e0434f4d
Exception Offset: 000000000000caed
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033
Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409
If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt
I wrapped the code in a try/catch, and still did not get a proper error message:
static void Main()
{
try
{
EnvDTE80.DTE2 dte;
object obj = null;
System.Type t = null;
// Get the ProgID for DTE 8.0.
t = System.Type.GetTypeFromProgID("VisualStudio.DTE.9.0",
true);
// Create a new instance of the IDE.
obj = System.Activator.CreateInstance(t, true);
// Cast the instance to DTE2 and assign to variable dte.
dte = (EnvDTE80.DTE2)obj;
// Register the IOleMessageFilter to handle any threading
// errors.
MessageFilter.Register();
// Display the Visual Studio IDE.
dte.MainWindow.Activate();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
// For example, get a reference to the solution2 object
// and do what you like with it.
// All done, so shut down the IDE...
dte.Quit();
// and turn off the IOleMessageFilter.
MessageFilter.Revoke();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
How can I identify where exactly the exception occurred and WHAT IS the exception?
I do have some unmanaged code:
using System;
using System.Collections.Generic;
using System.Text;
using EnvDTE;
using EnvDTE80;
using EnvDTE90;
using System.Runtime.InteropServices;
namespace EmailSalesVolumeSolution
{
public class MessageFilter : IOleMessageFilter
{
//
// Class containing the IOleMessageFilter
// thread error-handling functions.
// Start the filter.
public static void Register()
{
IOleMessageFilter newFilter = new MessageFilter();
IOleMessageFilter oldFilter = null;
CoRegisterMessageFilter(newFilter, out oldFilter);
}
// Done with the filter, close it.
public static void Revoke()
{
IOleMessageFilter oldFilter = null;
CoRegisterMessageFilter(null, out oldFilter);
}
//
// IOleMessageFilter functions.
// Handle incoming thread requests.
int IOleMessageFilter.HandleInComingCall(int dwCallType,
System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr
lpInterfaceInfo)
{
//Return the flag SERVERCALL_ISHANDLED.
return 0;
}
// Thread call was rejected, so try again.
int IOleMessageFilter.RetryRejectedCall(System.IntPtr
hTaskCallee, int dwTickCount, int dwRejectType)
{
if (dwRejectType == 2)
// flag = SERVERCALL_RETRYLATER.
{
// Retry the thread call immediately if return >=0 &
// <100.
return 99;
}
// Too busy; cancel call.
return -1;
}
int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
int dwTickCount, int dwPendingType)
{
//Return the flag PENDINGMSG_WAITDEFPROCESS.
return 2;
}
// Implement the IOleMessageFilter interface.
[DllImport("Ole32.dll")]
private static extern int
CoRegisterMessageFilter(IOleMessageFilter newFilter, out
IOleMessageFilter oldFilter);
}
[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IOleMessageFilter
{
[PreserveSig]
int HandleInComingCall(
int dwCallType,
IntPtr hTaskCaller,
int dwTickCount,
IntPtr lpInterfaceInfo);
[PreserveSig]
int RetryRejectedCall(
IntPtr hTaskCallee,
int dwTickCount,
int dwRejectType);
[PreserveSig]
int MessagePending(
IntPtr hTaskCallee,
int dwTickCount,
int dwPendingType);
}
}
after installing VS 2008 express on the machine that gave me trouble, i am now getting this:
You can try also to subscribe on AppDomain.CurrentDomain.UnhandledException event:
AppDomain.CurrentDomain.UnhandledException +=
(sender, e) => MessageBox.Show(e.ExceptionObject.ToString());
Do this at the top of Main method.
Try printing more from the Exception:
catch(Exception e)
{
MessageBox.Show(e.Message + ":\n" + e.StackTrace);
}
You can use this to catch all Inner Excpetions as well:
string except = "Uncaught Exception: ";
while(e != null)
{
except += e.Message + ";\n";
e = e.InnerException;
}
If program crashes with no exception then you need to try and attach a Debugger,
You'll need Visual Studio installed on the machine or to be able to use Remote Desktop for remote debugging. How to: Attach to a Running Process
To attach to a running process:
On the Debug menu, select Attach to Process.
In the Attach to Process dialog box, find the program that you want
to attach to from the Available Processes list.
If the program that you want to debug is running on another
computer, use the Qualifier list box to select the remote computer.
For more information, see How to: Select a Remote Machine.
If the process is running under a different user account, select the
Show processes from all users check box.
If you are connected through Remote Desktop Connection, select the
Show processes in all sessions check box.
In the Attach to box, make sure that the type of code you will debug
is listed. The default Automatic setting tries to determine what
type of code you want to debug. If the automatic setting is not
appropriate:
Click Select.
In the Select Code Type dialog box, click Debug these code types and
select the types to debug.
Click OK.
Click Attach.
You MUST compile the executable with DEBUG mode
UPDATE
I see you use Type.GetTypeFromProgID that requires .NET 4.5, Please make sure you have .NET 4.5 installed on the PC that is throwing the error !
It seems that t = System.Type.GetTypeFromProgID("VisualStudio.DTE.9.0", true); is throwing COMException that means that "VisualStudio.DTE.9.0" is not registered in the other PC.
You should add Microsoft Visual Studio 2008 DTE as a dependency for your program.
Your DLL may not be registered on the client machine. Check the DLL that you are calling the COM object for and do a Regsvr32 YouComDllName.dll in a administrative command prompt (right click on the command prompt icon and do Run as Administrator. Depending on if you are using a 32 bit or 64 bit application you may need to either use the copy of Regsvr32 in C:\Windows\System32 or in C:\Windows\SysWOW64 (In a backwards way the 64 bit version is in system32 and the 32 bit version is in SysWOW64)
If just regestering the DLL on your machine does not work run Dependancy Walker on the program on your computer. When you get all of the DLLs that your program touches, check the client computer is not missing any. The DLL you are calling may be there, but a DLL it depends on may not be.
The only solution that worked was installing Visual studio. As soon as it was installed, I got the exact exception.

Categories

Resources