Thanks — that crash in user32.dll on ShowDialog commonly means something in the UI call path (owner HWND, threading, or a native/COM call) is invalid and the exception is bubbling into native code. Below are focused, practical debugging steps and fixes you can run now (ordered from easiest to most detailed). Try them and tell me what you find (stack, dump, or output) and I’ll help interpret.
Quick checks & common fixes (do these first)
- Ensure your app’s UI thread is STA
- WinForms / ShowDialog must run on an STA thread. Confirm your program entry has [STAThread] (C#) and that you are not calling ShowDialog from a threadpool/background thread.
C# example:
- Program.cs
[STAThread]
static void Main {
Application.EnableVisualStyles;
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm;
}
If you need to show a dialog from a background thread, marshal to the UI thread or create a dedicated STA thread:
- Create an STA thread:
Thread t = new Thread( => { using (var f = new MyDialog f.ShowDialog; });
t.SetApartmentState(ApartmentState.STA);
t.Start;
- Check owner window and lifetime
- Don’t call someForm.ShowDialog(owner) with an owner that’s already closed/disposed or created on another thread. Try calling ShowDialog without an owner as a test.
- Ensure the form object isn’t disposed before ShowDialog.
- Add global exception handlers (to log managed exceptions)
- WinForms:
Application.ThreadException += (s,e) => Log(e.Exception);
AppDomain.CurrentDomain.UnhandledException += (s,e) => Log((Exception)e.ExceptionObject);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
This lets you see any managed exceptions before they hit native code.
If those fixes don’t resolve it, do this targeted debugging flow
A. Reproduce minimum test
- Create a tiny WinForms app that just does:
var dlg = new Form; dlg.ShowDialog;
If that crashes, it’s environmental (runtime / Windows / drivers). If it doesn’t, the problem is in your app’s dialog code (custom control/interop).
B. Break on first-chance exceptions in Visual Studio
- In VS: Debug → Windows → Exception Settings → check “Common Language Runtime Exceptions” (Thrown) and enable native exceptions if needed. Also enable mixed-mode debugging for your project (Project → Properties → Debug → Enable native code debugging). Run under debugger — it should break at the throw site with managed stack and call stack.
C. Get the full stack (managed + native)
- In VS when it breaks enable “Show external code” in Call Stack window, or use Debug→Windows→Call Stack and right-click → Show External Code.
- If it crashes without debugger, capture a dump (below) and open with WinDbg and run: .symfix; .reload; !analyze -v and then k / kv to see call stack.
How to capture a crash dump
- Easiest (when app running):
- Task Manager → Processes → right-click process → Create dump file. Path printed after creation.
- Using ProcDump (Sysinternals):
procdump -e 1 -ma -x C:\dumps YourApp.exe
(This waits for first chance exception/crash and writes full dump.
- If crash happens immediately, run your app under the debugger (VS or WinDbg) to catch it.
Analyze dump with WinDbg
- Open dump in WinDbg (x64). Then:
.symfix
.reload
!analyze -v
.ecxr ; gives exception context
k / kv ; show native stack with parameters
!CLRStack ; show managed stack (requires SOS: .loadby sos clr or .loadby sos coreclr)
- Look for your managed frame that called ShowDialog and any P/Invoke or custom control code below.
Specific things to look for in the stack / dump
- Is ShowDialog being invoked from a non-STA thread? (Check Thread.CurrentThread.ApartmentState or inspect managed stack).
- Is there a P/Invoke or COM call in your dialog constructor / Load / OnShown / Load event? Those often crash in user32 if parameters are invalid.
- Are there custom window message handlers or WindowProc overrides that might dereference invalid pointers?
- Does user32!CreateWindowEx / DefWindowProc show bad parameters?
Other actionable checks
- Update runtimes & drivers:
- Make sure .NET runtime (or .NET Framework) is up-to-date and installed correctly on the Windows 11 machines.
- Update display drivers (graphics driver bugs can cause user32 crashes on window operations).
- Test on both Windows 10 and Windows 11 to isolate change.
If you want to attempt a quick temporary mitigation
- Wrap the ShowDialog call in try/catch and log exception/stack:
try { dlg.ShowDialog; } catch (Exception ex) { Log(ex.ToString; throw; }
- Add logging in dialog constructor and Load/Shown/OnPaint to narrow which step causes the crash.
If you give me one of these I’ll analyze next:
- Managed stack trace when the debugger breaks (copy Call Stack with external frames),
- A crash dump file (I can walk you through analyzing or point to suspicious frames),
- The dialog’s constructor / Load / OnShown / custom control code (paste the code around where the dialog is created).
Quick checklist to run now
- Verify [STAThread] on Main.
- Run a minimal repro (new solution: one button -> new Form.ShowDialog.
- Run under VS with “Break on thrown” for CLR exceptions and mixed-mode debugging enabled.
- If still crashes, capture dump (Task Manager or ProcDump) and paste the !analyze -v output or the call stack here.
If you want, paste the small code that creates the dialog (the immediate caller and the dialog’s ctor/Load). I’ll scan for common pitfalls (cross-thread, invalid P/Invoke, unmanaged control usage) and point out exactly what to change.