What Debugging Steps Should I Take

RogerSchlueter-7899 1,801 Reputation points
2026-10-10T10:49:18.34+00:00

In a wpf application, there is one window (Transactions) that, when a use makes a ComBox selection, opens another window (Details) using this code:

Dim win As New TransactionDetails With {.Owner = Me}
If win.ShowDialog() Then SaveTransaction()

The TransactionDetails window includes a UserControl (Categories) so the Loaded event of Categoies window runs:

Private Sub LoadMe(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
	If ocCategories.Count = 0 Then PopulateCategories()
	win = Window.GetWindow(Parent)
	....
	cvsCategories = CType(Resources("cvsCategories"), CollectionViewSource)
	cvsCategories.Source = ocCategories
End Sub

When the End Sub line runs, the application pauses for about a second then just quits. No error messages. Nothing in the Output window. The CallStack window shows the expected calls but gets wiped clean when the application goes south. The XAML Binding Failures has no entries. Using Watch windows shows all variables have expected values.

I don't know what further debugging steps will tell me what the problem is. Any suggestions?

Developer technologies | Visual Studio | Debugging

Locked Question. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments
Answer recommended by moderator
RogerSchlueter-7899 1,801 Reputation points
2026-11-11T00:36:28.7933333+00:00

The problem with repeated calls resulted from a implicit recursion between the two windows. Once I fixed that both the repeated sub calls AND the OP problem went away. A twofer!

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

3 additional answers

Sort by: Newest
  1. Brian Pham (WICLOUD CORPORATION) 1,255 Reputation points Microsoft External Staff Moderator
    2026-10-12T03:59:20.93+00:00

    Hi @RogerSchlueter-7899 ,

    Thank you for the additional troubleshooting details. The new information helps narrow the investigation.

    Since changing ShutdownMode to OnExplicitShutdown did not affect the behavior, and Event Viewer logged an Application Error for PIM.exe with KERNELBASE.dll as the faulting module and exception code 0xc000041d, this appears more consistent with a process crash than a normal WPF shutdown.

    At this point, I would focus on three areas that are most likely to provide new diagnostic information.

    1.Log the actual dispatcher exception:

    -One detail that stands out is that your DispatcherUnhandledException handler appears to log dispatcher state, but not the exception itself.

    -If you are not already doing so, please log:

    Private Sub DispatcherUnhandledExceptionEventHandler(
     sender As Object,
     e As DispatcherUnhandledExceptionEventArgs)
    
     Debug.WriteLine("Exception:")
     
    
     Debug.WriteLine($"HasShutdownStarted: {e.Dispatcher.HasShutdownStarted}")
     Debug.WriteLine($"HasShutdownFinished: {e.Dispatcher.HasShutdownFinished}")
    
    End Sub
    

    -This may reveal the exception type, inner exception, and managed call stack. Do not set e.Handled = True while investigating.

    2.Investigate why Categories.Loaded runs twice

    -Your logs indicate that Categories.Loaded executes twice. As a diagnostic test, temporarily ensure that the initialization code runs only once and check whether the behavior changes.

    -If it does, investigate why the control is being recreated, reloaded, or re-parented. Since SelectTab also appears multiple times in the log, check whether it rebuilds part of the visual tree.

    3.Capture the first failing stack

    -If e.Exception does not reveal the cause, enable native code debugging and configure Visual Studio to break on both CLR and Win32 exceptions.

    -If Visual Studio still does not stop at the originating exception, capture a full crash dump and inspect the exception record and call stack.

    -At this stage, the most useful next evidence would be either the complete output from e.Exception.ToString() or the exception record and call stack from the crash dump. This should help identify whether the failure originates in application code, WPF processing, or another component.

    If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation. Thank you.

    Was this answer helpful?

  2. Bilal Younis Ahmad Jawarneh 81 Reputation points
    2026-10-11T09:07:06.89+00:00

    Hi Roger,

    The Event Viewer entry in your comment is the key clue. Exception code 0xc000041d is STATUS_FATAL_USER_CALLBACK_EXCEPTION. It means an exception was thrown while Windows was calling back into your process to deliver a window message (a user-mode callback from user32/win32k). Windows can't unwind an exception through that kernel boundary, so it terminates the process immediately in KERNELBASE.dll. That's why:

    • none of your managed handlers (DispatcherUnhandledException, AppDomain.UnhandledException) fire,
    • the Call Stack is wiped,
    • "Break on CLR exceptions" doesn't stop, because the original exception is often native (an access violation 0xc0000005 or a stack overflow 0xc00000fd) or gets swallowed and re-thrown inside the callback.

    In WPF this usually happens during a message that is sent synchronously while the modal dialog is shown and activated: activation, focus, WM_WINDOWPOSCHANGED, layout or render, or an owner/owned window change. Your timing (right after Loaded finishes, while ShowDialog is running) fits that pattern.

    Step 1 – Catch the original exception before Windows converts it

    1. Project Properties > Debug > Open debug launch profiles UI > tick Enable native code debugging (mixed mode).
    2. Debug > Windows > Exception Settings > tick Win32 Exceptions (all of them, especially 0xc0000005 and 0xc00000fd) as well as Common Language Runtime Exceptions.
    3. Tools > Options > Debugging > General > untick Enable Just My Code.
    4. Reproduce. The debugger should now break on the first-chance exception, with the real call stack still intact.

    Step 2 – If it still won't break, capture a crash dump automatically

    Run this once from an admin prompt to enable Windows Error Reporting full dumps for PIM.exe:

    reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\PIM.exe" /v DumpType /t REG_DWORD /d 2 /f
    

    Reproduce the crash, then open %LOCALAPPDATA%\CrashDumps\PIM.exe.*.dmp in Visual Studio and choose Debug with Mixed. Alternatively, run procdump -ma -e 1 -f "" PIM.exe to dump on the first-chance exception. In WinDbg, !analyze -v followed by .ecxr; k shows the frame that threw.

    Step 3 – Quick isolation tests while you investigate

    • Fix the double Loaded first. A control that loads twice usually means it is being re-parented or re-templated while the dialog is showing, which is exactly the kind of re-entrancy that ends in a callback exception. Add a guard (If _loaded Then Return) and see whether the crash changes.
    • Defer the work out of the callback. Wrap the body of LoadMe in Dispatcher.BeginInvoke(Sub() ... , DispatcherPriority.Loaded) so that PopulateCategories and the cvsCategories.Source assignment run after the current message completes. If the crash disappears, you've confirmed the cause is re-entrancy during activation/layout.
    • Rule out the GPU path. Temporarily add RenderOptions.ProcessRenderMode = Interop.RenderMode.SoftwareOnly in Application_Startup. If the crash stops, it's a render/driver issue rather than your code.
    • Check anything native in the visual tree of TransactionDetails or Categories: HwndHost, WindowsFormsHost, WebView2, custom WndProc hooks (HwndSource.AddHook), or third-party controls. An exception thrown inside a hook is a classic cause of 0xc000041d.

    Once Step 1 or Step 2 shows the first-chance exception and its stack, post it here and I can help pinpoint the exact line.

    Reference: Debug StackOverflow errors (.NET), Collecting user-mode dumps (WER LocalDumps)

    Was this answer helpful?

    0 comments No comments
  3. Marcin Policht 112.7K Reputation points MVP Volunteer Moderator
    2026-10-10T11:01:22.3233333+00:00

    The fact that the application exits without an exception message, and that the Call Stack disappears, suggests that you should investigate whether the process is terminating unexpectedly rather than assume that the Loaded event is throwing an ordinary exception. In WPF, this can happen because of an unhandled exception on another dispatcher or thread, an explicit application shutdown, a native or runtime failure, or an exception that Visual Studio is not configured to break on. The one-second delay after End Sub is also significant: the failure may occur during subsequent WPF layout, data binding, rendering, or another event rather than inside LoadMe itself.

    I would approach this systematically, starting with the following steps.

    First, configure Visual Studio to break when an exception is thrown. Open Debug → Windows → Exception Settings and enable breaking on thrown exceptions for Common Language Runtime Exceptions. Run the application again. This is important because an exception may be caught internally by WPF or your application, or may occur after your event handler returns. If Visual Studio breaks on an exception, inspect the exception type, message, and call stack before continuing. If the application still exits without breaking, that points toward a different kind of termination or a failure outside the normal managed exception path.

    Second, determine whether the application is actually crashing or shutting down normally. Add temporary diagnostic code to the application-level App.xaml.vb file. In the Application_Startup event, register handlers for AppDomain.CurrentDomain.UnhandledException and TaskScheduler.UnobservedTaskException, and add a handler for Application.Current.DispatcherUnhandledException. Log the exception details to a text file rather than relying solely on the Output window. For example, the dispatcher handler can log e.Exception.ToString(). Do not automatically mark the exception as handled while investigating, because that can conceal the underlying problem. Note that these handlers cannot capture every type of process termination, and UnobservedTaskException is not a general-purpose handler for all asynchronous failures.

    Third, add logging immediately after the Loaded handler returns and around the dialog call. In the Transactions window, temporarily change the code to log before and after ShowDialog() and before and after SaveTransaction(). In Categories, log the entry to LoadMe, the completion of PopulateCategories(), the assignment to win, the retrieval of cvsCategories, the assignment of its Source, and the final exit from the handler. Include timestamps in each entry. This will tell you whether the process terminates while the dialog is still open, while WPF is processing the next layout or rendering cycle, or after the dialog closes and execution returns to Transactions.

    Fourth, investigate the CollectionViewSource and its associated XAML. The code shown does not, by itself, identify an obvious cause of process termination. Nevertheless, temporarily comment out cvsCategories.Source = ocCategories and test again. If the application stops exiting, investigate what the view source triggers: collection-change notifications, sorting or grouping logic, converters, data templates, and event handlers that execute when the view refreshes. If commenting out the assignment makes no difference, restore it and test with PopulateCategories() temporarily disabled. These controlled tests can isolate the component that triggers the problem.

    Fifth, check the application's shutdown configuration. Look at ShutdownMode in App.xaml and any code that calls Application.Current.Shutdown(), closes the main window, or handles the Closing and Closed events. Your use of ShowDialog() makes TransactionDetails a modal window, but the fact that Transactions is its owner does not prevent the application from shutting down for other reasons. If the application is configured with ShutdownMode="OnLastWindowClose", closing the last open window will end the application. Check whether any code closes either window unexpectedly or whether a binding, event handler, or validation routine triggers a close operation.

    Sixth, check the Windows application and crash logs. Open Windows Event Viewer and inspect Windows Logs → Application around the time of the failure. Look for entries from .NET Runtime or Application Error, including the exception code, faulting module, and application name. A native access violation or another runtime-level failure may terminate the process without producing a normal managed exception or a useful WPF binding error. If you find an event, the faulting module and exception code will help narrow down the investigation.

    Seventh, inspect the window and control lifecycle. Since the failure appears shortly after the Categories.Loaded handler finishes, temporarily add handlers for Unloaded, Closing, and Closed on the relevant windows, and log when they fire. Also inspect any Dispatcher.BeginInvoke, asynchronous tasks, timers, event subscriptions, or callbacks initiated by PopulateCategories() or by code that runs when the category collection changes. The code executing immediately after End Sub may be the trigger, even if the debugger appears to implicate that line.

    One detail worth checking in your existing code is win = Window.GetWindow(Parent). The method returns the window containing the specified element, or Nothing if the element is not attached to a window. Since you report that the value is correct in the Watch window, this is probably not the immediate issue. However, if win is later used by event handlers or asynchronous callbacks, verify that those callbacks are not acting on a window that has already closed.


    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin

    Was this answer helpful?