AccessibleObjectFromEvent call inside SetWinEventHook callback causes deadlocks
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
Both the callback and the AccessibleObjectFromEvent call appear to be working as intended, and I'm not using any locking mechanisms, but if AccessibleObjectFromEvent is present in the callback the winforms form will occasionally lock up.
I noticed when it freezes it has this odd property where right-clicking on its taskbar icon unfreezes it.
Pausing with the debugger just takes you to Application.Run(new Form1())
, and nothing appears blocked on the .Net side - the debugger's window updates can even trigger some Active Accessibility events and then let you step through those events in the callback - working - all while the form remains frozen!
I note that AccessibleObjectFromEvent works by sending a WM_GETOBJECT message, but the .Net side is never stuck at the AccessibleObjectFromEvent call, and calling AccessibleObjectFromEvent from inside a SetWinEventHook callback is AFAIK a normal way to do Active Accessibility.
I've not noticed any correlation with Active Accessibility events when it freezes, but I don't really have enough information to rule that out. I also tried it compiled x86 (instead of Any), and that made no difference.
I boiled it down to its most minimal form:
using Accessibility;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
static class Program {
// PInvoke declarations, see http://www.pinvoke.net/default.aspx/user32.setwineventhook
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, WinEventFlag dwFlags);
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("oleacc.dll")]
public static extern uint AccessibleObjectFromEvent(IntPtr hwnd, uint dwObjectID, uint dwChildID, out IAccessible ppacc, [MarshalAs(UnmanagedType.Struct)] out object pvarChild);
[Flags]
public enum WinEventFlag : uint {
/// <summary>Events are ASYNC</summary>
Outofcontext = 0x0000,
/// <summary>Don't call back for events on installer's thread</summary>
Skipownthread = 0x0001,
/// <summary>Don't call back for events on installer's process</summary>
Skipownprocess = 0x0002,
/// <summary>Events are SYNC, this causes your dll to be injected into every process</summary>
Incontext = 0x0004
}
static IntPtr hookHandle = IntPtr.Zero;
static GCHandle garbageCollectorHandle;
static void AccessibilityEventHandler(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
try {
object objChild = null;
IAccessible accWindow = null;
AccessibleObjectFromEvent(hWnd, (uint)idObject, (uint)idChild, out accWindow, out objChild);
Debug.WriteLine("Hook was invoked");
} catch (Exception ex) {
Debug.WriteLine("Exception " + ex);
}
}
[STAThread]
static void Main() {
WinEventDelegate callback = new WinEventDelegate(AccessibilityEventHandler);
// Use the member garbageCollectorHandle to keep the delegate object in memory. Might not be needed, and can't properly pin it because it's not a primitive type.
garbageCollectorHandle = GCHandle.Alloc(callback);
SetWinEventHook(
0x7546, // eventMin (0x7546 = PropertyChanged_IsOffscreen)
0x7546, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
// Two hooks are not necessary to cause a freeze, but with two it can happen much faster - sometimes within minutes
SetWinEventHook(
0x0001, // eventMin (0x0001 = System_Sound)
0x0001, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
With such a minimal app it's harder to notice the message pump freeze, but you won't be able to drag the window or bring it to the foreground once it's locked. The bug is intermittent, often it happens within 5 minutes, sometimes it takes so long I give up, if you leave it overnight and the form is still responsive in the morning then it might depend on machine/OS (tried on Win 10.0.17174 and 10.0.17763, .net 4.5.2 and 4.6.1).
I'm 99% sure the call to AccessibleObjectFromEvent is required for the app to freeze, but with intermittent freezes there's no way to absolutely know for sure.
Reentrancy
Following Jimi's suggestions in the comments, I ran the minimal app with the flags
WinEventFlag.Outofcontext | WinEventFlag.Skipownthread | WinEventFlag.Skipownprocess
It took a while to freeze, but has still frozen. The Debug.WriteLine()
calls indicate it's still responding to Active Accessibility events normally - i.e. no recursive busy-loop is happening through that callback (at least not now that I'm looking), but the form is frozen. It's using 0% CPU in the task manager.
The freeze is slightly different now, in that the task manager doesn't list it as "not responding" and I can bring it to the foreground by left-clicking the taskbar icon - normally the taskbar can't even bring it to the foreground. However the form still can't be moved or resized, and you can't bring the form to the foreground by clicking on it.
I'd also added some Debug.WriteLine in front of the AccessibleObjectFromEvent call, and tracked reentrancy depth, I can see that it is occasionally reentrant, but usually to a depth of only one before unwinding, and no deeper than 13 before fully unwinding. This appears to be caused by there being many events already in the message queue, rather than the hook handler recursively causing events it must then handle. The UI is currently frozen and the hook handler is 0 deep (i.e. not currently reentrant).
c# .net winforms winapi deadlock
add a comment |
Both the callback and the AccessibleObjectFromEvent call appear to be working as intended, and I'm not using any locking mechanisms, but if AccessibleObjectFromEvent is present in the callback the winforms form will occasionally lock up.
I noticed when it freezes it has this odd property where right-clicking on its taskbar icon unfreezes it.
Pausing with the debugger just takes you to Application.Run(new Form1())
, and nothing appears blocked on the .Net side - the debugger's window updates can even trigger some Active Accessibility events and then let you step through those events in the callback - working - all while the form remains frozen!
I note that AccessibleObjectFromEvent works by sending a WM_GETOBJECT message, but the .Net side is never stuck at the AccessibleObjectFromEvent call, and calling AccessibleObjectFromEvent from inside a SetWinEventHook callback is AFAIK a normal way to do Active Accessibility.
I've not noticed any correlation with Active Accessibility events when it freezes, but I don't really have enough information to rule that out. I also tried it compiled x86 (instead of Any), and that made no difference.
I boiled it down to its most minimal form:
using Accessibility;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
static class Program {
// PInvoke declarations, see http://www.pinvoke.net/default.aspx/user32.setwineventhook
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, WinEventFlag dwFlags);
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("oleacc.dll")]
public static extern uint AccessibleObjectFromEvent(IntPtr hwnd, uint dwObjectID, uint dwChildID, out IAccessible ppacc, [MarshalAs(UnmanagedType.Struct)] out object pvarChild);
[Flags]
public enum WinEventFlag : uint {
/// <summary>Events are ASYNC</summary>
Outofcontext = 0x0000,
/// <summary>Don't call back for events on installer's thread</summary>
Skipownthread = 0x0001,
/// <summary>Don't call back for events on installer's process</summary>
Skipownprocess = 0x0002,
/// <summary>Events are SYNC, this causes your dll to be injected into every process</summary>
Incontext = 0x0004
}
static IntPtr hookHandle = IntPtr.Zero;
static GCHandle garbageCollectorHandle;
static void AccessibilityEventHandler(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
try {
object objChild = null;
IAccessible accWindow = null;
AccessibleObjectFromEvent(hWnd, (uint)idObject, (uint)idChild, out accWindow, out objChild);
Debug.WriteLine("Hook was invoked");
} catch (Exception ex) {
Debug.WriteLine("Exception " + ex);
}
}
[STAThread]
static void Main() {
WinEventDelegate callback = new WinEventDelegate(AccessibilityEventHandler);
// Use the member garbageCollectorHandle to keep the delegate object in memory. Might not be needed, and can't properly pin it because it's not a primitive type.
garbageCollectorHandle = GCHandle.Alloc(callback);
SetWinEventHook(
0x7546, // eventMin (0x7546 = PropertyChanged_IsOffscreen)
0x7546, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
// Two hooks are not necessary to cause a freeze, but with two it can happen much faster - sometimes within minutes
SetWinEventHook(
0x0001, // eventMin (0x0001 = System_Sound)
0x0001, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
With such a minimal app it's harder to notice the message pump freeze, but you won't be able to drag the window or bring it to the foreground once it's locked. The bug is intermittent, often it happens within 5 minutes, sometimes it takes so long I give up, if you leave it overnight and the form is still responsive in the morning then it might depend on machine/OS (tried on Win 10.0.17174 and 10.0.17763, .net 4.5.2 and 4.6.1).
I'm 99% sure the call to AccessibleObjectFromEvent is required for the app to freeze, but with intermittent freezes there's no way to absolutely know for sure.
Reentrancy
Following Jimi's suggestions in the comments, I ran the minimal app with the flags
WinEventFlag.Outofcontext | WinEventFlag.Skipownthread | WinEventFlag.Skipownprocess
It took a while to freeze, but has still frozen. The Debug.WriteLine()
calls indicate it's still responding to Active Accessibility events normally - i.e. no recursive busy-loop is happening through that callback (at least not now that I'm looking), but the form is frozen. It's using 0% CPU in the task manager.
The freeze is slightly different now, in that the task manager doesn't list it as "not responding" and I can bring it to the foreground by left-clicking the taskbar icon - normally the taskbar can't even bring it to the foreground. However the form still can't be moved or resized, and you can't bring the form to the foreground by clicking on it.
I'd also added some Debug.WriteLine in front of the AccessibleObjectFromEvent call, and tracked reentrancy depth, I can see that it is occasionally reentrant, but usually to a depth of only one before unwinding, and no deeper than 13 before fully unwinding. This appears to be caused by there being many events already in the message queue, rather than the hook handler recursively causing events it must then handle. The UI is currently frozen and the hook handler is 0 deep (i.e. not currently reentrant).
c# .net winforms winapi deadlock
I would addWINEVENT_SKIPOWNTHREAD = 0x0001
andWINEVENT_SKIPOWNPROCESS = 0x0002
toWinEventFlag.Outofcontext
.
– Jimi
Jan 4 at 1:02
I've seen it occur with both of those flags set, though I've not tried them both at the same time. I'll confirm it still happens and if so I'll update the code in the question.
– Treer
Jan 4 at 1:05
1
See also: Guarding Against Reentrancy in Hook Functions
– Jimi
Jan 4 at 1:17
1
There is no practical way to debug these kind of deadlocks, they occur in ring0 kernel code. Possible ways to get ahead are removing the jitter forcing (Project > Properties > Build tab) so the process can run in 64-bit mode, stay away from event 0x7546 for now and using Application.OpenForms[0].BeginInvoke() to run the Debug.WriteLine code and minimize the re-entrancy risks. You also need to test this on a relatively clean machine, minimizing the risk of another Automation client causing this problem. Do document the Windows version.
– Hans Passant
Jan 5 at 15:41
Thanks. I've added the Win version (10.0.17174 and 10.0.17763) and will try on a cleaner machine. The 0x7546 events could well be part of the problem, they looked to be the only useful Active Accessibility event for awareness of UWP alerts/toasts/Action Center, but hopefully there is a better API a desktop app can use for that special case.
– Treer
Jan 6 at 7:06
add a comment |
Both the callback and the AccessibleObjectFromEvent call appear to be working as intended, and I'm not using any locking mechanisms, but if AccessibleObjectFromEvent is present in the callback the winforms form will occasionally lock up.
I noticed when it freezes it has this odd property where right-clicking on its taskbar icon unfreezes it.
Pausing with the debugger just takes you to Application.Run(new Form1())
, and nothing appears blocked on the .Net side - the debugger's window updates can even trigger some Active Accessibility events and then let you step through those events in the callback - working - all while the form remains frozen!
I note that AccessibleObjectFromEvent works by sending a WM_GETOBJECT message, but the .Net side is never stuck at the AccessibleObjectFromEvent call, and calling AccessibleObjectFromEvent from inside a SetWinEventHook callback is AFAIK a normal way to do Active Accessibility.
I've not noticed any correlation with Active Accessibility events when it freezes, but I don't really have enough information to rule that out. I also tried it compiled x86 (instead of Any), and that made no difference.
I boiled it down to its most minimal form:
using Accessibility;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
static class Program {
// PInvoke declarations, see http://www.pinvoke.net/default.aspx/user32.setwineventhook
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, WinEventFlag dwFlags);
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("oleacc.dll")]
public static extern uint AccessibleObjectFromEvent(IntPtr hwnd, uint dwObjectID, uint dwChildID, out IAccessible ppacc, [MarshalAs(UnmanagedType.Struct)] out object pvarChild);
[Flags]
public enum WinEventFlag : uint {
/// <summary>Events are ASYNC</summary>
Outofcontext = 0x0000,
/// <summary>Don't call back for events on installer's thread</summary>
Skipownthread = 0x0001,
/// <summary>Don't call back for events on installer's process</summary>
Skipownprocess = 0x0002,
/// <summary>Events are SYNC, this causes your dll to be injected into every process</summary>
Incontext = 0x0004
}
static IntPtr hookHandle = IntPtr.Zero;
static GCHandle garbageCollectorHandle;
static void AccessibilityEventHandler(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
try {
object objChild = null;
IAccessible accWindow = null;
AccessibleObjectFromEvent(hWnd, (uint)idObject, (uint)idChild, out accWindow, out objChild);
Debug.WriteLine("Hook was invoked");
} catch (Exception ex) {
Debug.WriteLine("Exception " + ex);
}
}
[STAThread]
static void Main() {
WinEventDelegate callback = new WinEventDelegate(AccessibilityEventHandler);
// Use the member garbageCollectorHandle to keep the delegate object in memory. Might not be needed, and can't properly pin it because it's not a primitive type.
garbageCollectorHandle = GCHandle.Alloc(callback);
SetWinEventHook(
0x7546, // eventMin (0x7546 = PropertyChanged_IsOffscreen)
0x7546, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
// Two hooks are not necessary to cause a freeze, but with two it can happen much faster - sometimes within minutes
SetWinEventHook(
0x0001, // eventMin (0x0001 = System_Sound)
0x0001, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
With such a minimal app it's harder to notice the message pump freeze, but you won't be able to drag the window or bring it to the foreground once it's locked. The bug is intermittent, often it happens within 5 minutes, sometimes it takes so long I give up, if you leave it overnight and the form is still responsive in the morning then it might depend on machine/OS (tried on Win 10.0.17174 and 10.0.17763, .net 4.5.2 and 4.6.1).
I'm 99% sure the call to AccessibleObjectFromEvent is required for the app to freeze, but with intermittent freezes there's no way to absolutely know for sure.
Reentrancy
Following Jimi's suggestions in the comments, I ran the minimal app with the flags
WinEventFlag.Outofcontext | WinEventFlag.Skipownthread | WinEventFlag.Skipownprocess
It took a while to freeze, but has still frozen. The Debug.WriteLine()
calls indicate it's still responding to Active Accessibility events normally - i.e. no recursive busy-loop is happening through that callback (at least not now that I'm looking), but the form is frozen. It's using 0% CPU in the task manager.
The freeze is slightly different now, in that the task manager doesn't list it as "not responding" and I can bring it to the foreground by left-clicking the taskbar icon - normally the taskbar can't even bring it to the foreground. However the form still can't be moved or resized, and you can't bring the form to the foreground by clicking on it.
I'd also added some Debug.WriteLine in front of the AccessibleObjectFromEvent call, and tracked reentrancy depth, I can see that it is occasionally reentrant, but usually to a depth of only one before unwinding, and no deeper than 13 before fully unwinding. This appears to be caused by there being many events already in the message queue, rather than the hook handler recursively causing events it must then handle. The UI is currently frozen and the hook handler is 0 deep (i.e. not currently reentrant).
c# .net winforms winapi deadlock
Both the callback and the AccessibleObjectFromEvent call appear to be working as intended, and I'm not using any locking mechanisms, but if AccessibleObjectFromEvent is present in the callback the winforms form will occasionally lock up.
I noticed when it freezes it has this odd property where right-clicking on its taskbar icon unfreezes it.
Pausing with the debugger just takes you to Application.Run(new Form1())
, and nothing appears blocked on the .Net side - the debugger's window updates can even trigger some Active Accessibility events and then let you step through those events in the callback - working - all while the form remains frozen!
I note that AccessibleObjectFromEvent works by sending a WM_GETOBJECT message, but the .Net side is never stuck at the AccessibleObjectFromEvent call, and calling AccessibleObjectFromEvent from inside a SetWinEventHook callback is AFAIK a normal way to do Active Accessibility.
I've not noticed any correlation with Active Accessibility events when it freezes, but I don't really have enough information to rule that out. I also tried it compiled x86 (instead of Any), and that made no difference.
I boiled it down to its most minimal form:
using Accessibility;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
static class Program {
// PInvoke declarations, see http://www.pinvoke.net/default.aspx/user32.setwineventhook
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, WinEventFlag dwFlags);
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("oleacc.dll")]
public static extern uint AccessibleObjectFromEvent(IntPtr hwnd, uint dwObjectID, uint dwChildID, out IAccessible ppacc, [MarshalAs(UnmanagedType.Struct)] out object pvarChild);
[Flags]
public enum WinEventFlag : uint {
/// <summary>Events are ASYNC</summary>
Outofcontext = 0x0000,
/// <summary>Don't call back for events on installer's thread</summary>
Skipownthread = 0x0001,
/// <summary>Don't call back for events on installer's process</summary>
Skipownprocess = 0x0002,
/// <summary>Events are SYNC, this causes your dll to be injected into every process</summary>
Incontext = 0x0004
}
static IntPtr hookHandle = IntPtr.Zero;
static GCHandle garbageCollectorHandle;
static void AccessibilityEventHandler(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
try {
object objChild = null;
IAccessible accWindow = null;
AccessibleObjectFromEvent(hWnd, (uint)idObject, (uint)idChild, out accWindow, out objChild);
Debug.WriteLine("Hook was invoked");
} catch (Exception ex) {
Debug.WriteLine("Exception " + ex);
}
}
[STAThread]
static void Main() {
WinEventDelegate callback = new WinEventDelegate(AccessibilityEventHandler);
// Use the member garbageCollectorHandle to keep the delegate object in memory. Might not be needed, and can't properly pin it because it's not a primitive type.
garbageCollectorHandle = GCHandle.Alloc(callback);
SetWinEventHook(
0x7546, // eventMin (0x7546 = PropertyChanged_IsOffscreen)
0x7546, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
// Two hooks are not necessary to cause a freeze, but with two it can happen much faster - sometimes within minutes
SetWinEventHook(
0x0001, // eventMin (0x0001 = System_Sound)
0x0001, // eventMax
IntPtr.Zero,
callback,
0,
0,
WinEventFlag.Outofcontext
);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
With such a minimal app it's harder to notice the message pump freeze, but you won't be able to drag the window or bring it to the foreground once it's locked. The bug is intermittent, often it happens within 5 minutes, sometimes it takes so long I give up, if you leave it overnight and the form is still responsive in the morning then it might depend on machine/OS (tried on Win 10.0.17174 and 10.0.17763, .net 4.5.2 and 4.6.1).
I'm 99% sure the call to AccessibleObjectFromEvent is required for the app to freeze, but with intermittent freezes there's no way to absolutely know for sure.
Reentrancy
Following Jimi's suggestions in the comments, I ran the minimal app with the flags
WinEventFlag.Outofcontext | WinEventFlag.Skipownthread | WinEventFlag.Skipownprocess
It took a while to freeze, but has still frozen. The Debug.WriteLine()
calls indicate it's still responding to Active Accessibility events normally - i.e. no recursive busy-loop is happening through that callback (at least not now that I'm looking), but the form is frozen. It's using 0% CPU in the task manager.
The freeze is slightly different now, in that the task manager doesn't list it as "not responding" and I can bring it to the foreground by left-clicking the taskbar icon - normally the taskbar can't even bring it to the foreground. However the form still can't be moved or resized, and you can't bring the form to the foreground by clicking on it.
I'd also added some Debug.WriteLine in front of the AccessibleObjectFromEvent call, and tracked reentrancy depth, I can see that it is occasionally reentrant, but usually to a depth of only one before unwinding, and no deeper than 13 before fully unwinding. This appears to be caused by there being many events already in the message queue, rather than the hook handler recursively causing events it must then handle. The UI is currently frozen and the hook handler is 0 deep (i.e. not currently reentrant).
c# .net winforms winapi deadlock
c# .net winforms winapi deadlock
edited Jan 6 at 6:42
Treer
asked Jan 4 at 0:28
TreerTreer
370310
370310
I would addWINEVENT_SKIPOWNTHREAD = 0x0001
andWINEVENT_SKIPOWNPROCESS = 0x0002
toWinEventFlag.Outofcontext
.
– Jimi
Jan 4 at 1:02
I've seen it occur with both of those flags set, though I've not tried them both at the same time. I'll confirm it still happens and if so I'll update the code in the question.
– Treer
Jan 4 at 1:05
1
See also: Guarding Against Reentrancy in Hook Functions
– Jimi
Jan 4 at 1:17
1
There is no practical way to debug these kind of deadlocks, they occur in ring0 kernel code. Possible ways to get ahead are removing the jitter forcing (Project > Properties > Build tab) so the process can run in 64-bit mode, stay away from event 0x7546 for now and using Application.OpenForms[0].BeginInvoke() to run the Debug.WriteLine code and minimize the re-entrancy risks. You also need to test this on a relatively clean machine, minimizing the risk of another Automation client causing this problem. Do document the Windows version.
– Hans Passant
Jan 5 at 15:41
Thanks. I've added the Win version (10.0.17174 and 10.0.17763) and will try on a cleaner machine. The 0x7546 events could well be part of the problem, they looked to be the only useful Active Accessibility event for awareness of UWP alerts/toasts/Action Center, but hopefully there is a better API a desktop app can use for that special case.
– Treer
Jan 6 at 7:06
add a comment |
I would addWINEVENT_SKIPOWNTHREAD = 0x0001
andWINEVENT_SKIPOWNPROCESS = 0x0002
toWinEventFlag.Outofcontext
.
– Jimi
Jan 4 at 1:02
I've seen it occur with both of those flags set, though I've not tried them both at the same time. I'll confirm it still happens and if so I'll update the code in the question.
– Treer
Jan 4 at 1:05
1
See also: Guarding Against Reentrancy in Hook Functions
– Jimi
Jan 4 at 1:17
1
There is no practical way to debug these kind of deadlocks, they occur in ring0 kernel code. Possible ways to get ahead are removing the jitter forcing (Project > Properties > Build tab) so the process can run in 64-bit mode, stay away from event 0x7546 for now and using Application.OpenForms[0].BeginInvoke() to run the Debug.WriteLine code and minimize the re-entrancy risks. You also need to test this on a relatively clean machine, minimizing the risk of another Automation client causing this problem. Do document the Windows version.
– Hans Passant
Jan 5 at 15:41
Thanks. I've added the Win version (10.0.17174 and 10.0.17763) and will try on a cleaner machine. The 0x7546 events could well be part of the problem, they looked to be the only useful Active Accessibility event for awareness of UWP alerts/toasts/Action Center, but hopefully there is a better API a desktop app can use for that special case.
– Treer
Jan 6 at 7:06
I would add
WINEVENT_SKIPOWNTHREAD = 0x0001
and WINEVENT_SKIPOWNPROCESS = 0x0002
to WinEventFlag.Outofcontext
.– Jimi
Jan 4 at 1:02
I would add
WINEVENT_SKIPOWNTHREAD = 0x0001
and WINEVENT_SKIPOWNPROCESS = 0x0002
to WinEventFlag.Outofcontext
.– Jimi
Jan 4 at 1:02
I've seen it occur with both of those flags set, though I've not tried them both at the same time. I'll confirm it still happens and if so I'll update the code in the question.
– Treer
Jan 4 at 1:05
I've seen it occur with both of those flags set, though I've not tried them both at the same time. I'll confirm it still happens and if so I'll update the code in the question.
– Treer
Jan 4 at 1:05
1
1
See also: Guarding Against Reentrancy in Hook Functions
– Jimi
Jan 4 at 1:17
See also: Guarding Against Reentrancy in Hook Functions
– Jimi
Jan 4 at 1:17
1
1
There is no practical way to debug these kind of deadlocks, they occur in ring0 kernel code. Possible ways to get ahead are removing the jitter forcing (Project > Properties > Build tab) so the process can run in 64-bit mode, stay away from event 0x7546 for now and using Application.OpenForms[0].BeginInvoke() to run the Debug.WriteLine code and minimize the re-entrancy risks. You also need to test this on a relatively clean machine, minimizing the risk of another Automation client causing this problem. Do document the Windows version.
– Hans Passant
Jan 5 at 15:41
There is no practical way to debug these kind of deadlocks, they occur in ring0 kernel code. Possible ways to get ahead are removing the jitter forcing (Project > Properties > Build tab) so the process can run in 64-bit mode, stay away from event 0x7546 for now and using Application.OpenForms[0].BeginInvoke() to run the Debug.WriteLine code and minimize the re-entrancy risks. You also need to test this on a relatively clean machine, minimizing the risk of another Automation client causing this problem. Do document the Windows version.
– Hans Passant
Jan 5 at 15:41
Thanks. I've added the Win version (10.0.17174 and 10.0.17763) and will try on a cleaner machine. The 0x7546 events could well be part of the problem, they looked to be the only useful Active Accessibility event for awareness of UWP alerts/toasts/Action Center, but hopefully there is a better API a desktop app can use for that special case.
– Treer
Jan 6 at 7:06
Thanks. I've added the Win version (10.0.17174 and 10.0.17763) and will try on a cleaner machine. The 0x7546 events could well be part of the problem, they looked to be the only useful Active Accessibility event for awareness of UWP alerts/toasts/Action Center, but hopefully there is a better API a desktop app can use for that special case.
– Treer
Jan 6 at 7:06
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54031673%2faccessibleobjectfromevent-call-inside-setwineventhook-callback-causes-deadlocks%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54031673%2faccessibleobjectfromevent-call-inside-setwineventhook-callback-causes-deadlocks%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I would add
WINEVENT_SKIPOWNTHREAD = 0x0001
andWINEVENT_SKIPOWNPROCESS = 0x0002
toWinEventFlag.Outofcontext
.– Jimi
Jan 4 at 1:02
I've seen it occur with both of those flags set, though I've not tried them both at the same time. I'll confirm it still happens and if so I'll update the code in the question.
– Treer
Jan 4 at 1:05
1
See also: Guarding Against Reentrancy in Hook Functions
– Jimi
Jan 4 at 1:17
1
There is no practical way to debug these kind of deadlocks, they occur in ring0 kernel code. Possible ways to get ahead are removing the jitter forcing (Project > Properties > Build tab) so the process can run in 64-bit mode, stay away from event 0x7546 for now and using Application.OpenForms[0].BeginInvoke() to run the Debug.WriteLine code and minimize the re-entrancy risks. You also need to test this on a relatively clean machine, minimizing the risk of another Automation client causing this problem. Do document the Windows version.
– Hans Passant
Jan 5 at 15:41
Thanks. I've added the Win version (10.0.17174 and 10.0.17763) and will try on a cleaner machine. The 0x7546 events could well be part of the problem, they looked to be the only useful Active Accessibility event for awareness of UWP alerts/toasts/Action Center, but hopefully there is a better API a desktop app can use for that special case.
– Treer
Jan 6 at 7:06