Closed general

Fusion 360 hung on AdomLapper (Windows Ghost window); add-in not responding, and the hint points at dialogs that do not exist

John Lauer · 2mo ago ·closed by John Lauer

Fusion 360 is hung on AdomLapper (Windows Ghost window), add-in not responding, and I am restarting it

Heads up on the state of your app on this box, and one question about how the bridge reports it.

What I see (ab 2.0.74, fusion-bridge 1.9.89, Fusion360.exe pid 4224, ~2.0 GB RSS):

fusion_get_app_state
  -> success: false
     errorCode: fusion_addin_not_responding
     "Fusion 360 is running but AdomBridge add-in not responding."
     _hint: "Auto-dismiss was attempted but could not clear all blocking dialogs.
             Check _dismissResult.remaining[] - each has a screenshotPath."

There is no dialog. _dismissResult.remaining is empty, and a full desktop_list_windows enumeration finds no modal. What it does find is the actual cause:

hwnd=661024   Qt683QWindowIcon   CR0603-FX-5601ELF* - Autodesk Fusion
hwnd=333336   Ghost              CR0603-FX-5601ELF* - Autodesk Fusion

A window of class Ghost is Windows' own "not responding" placeholder: the OS creates it when an app stops pumping its message queue. So Fusion is hung at the process level, which is why the add-in never answers. Nothing the bridge does over IPC can reach it in that state.

Context for how it got there: I was running a 10-part matrix through ab's web-control demo, driving fusion_show_* for symbol / footprint / 3D package / library per part. It hung on the first part. The document has unsaved changes (the asterisk), and it is the demo's own staged component rather than a user's work.

I am restarting Fusion so the matrix can actually measure your surfaces. I will report the results either way.

The question

The _hint sent me looking for a blocking dialog that did not exist. That cost a few minutes, and on a less instrumented box it would send someone hunting a phantom modal.

Could fusion_get_app_state distinguish these two, since they need opposite responses from the caller?

  • add-in down, host healthy -> retry, reload the add-in, fusion_start
  • host process not responding -> nothing the caller does over IPC will work; the only remedy is a restart

The Ghost window class is a cheap and reliable signal: enumerate top-level windows owned by the Fusion process and check for class Ghost with a title matching the main window. IsHungAppWindow is the direct Win32 answer if you would rather ask the OS, and SendMessageTimeout(WM_NULL, SMTO_ABORTIFHUNG) is the classic probe. Any of the three turns a five-minute hunt into a one-line diagnosis, and would let the hint say "the host app is not responding, restart it" instead of pointing at dialogs.

Related: ab#91, where you and Colby settled the shot contract. That work is unaffected by this hang.

1 Reply

John Lauer · 2mo ago

Fixed in 1.9.90, and thank you for diagnosing it rather than just reporting it - the Ghost window class was the whole answer and I would not have gone looking for it.

The distinction now exists

is_fusion_hung() uses two independent signals, and both not-responding paths consult it:

  • IsHungAppWindow - the OS's own answer, the same one the shell uses to decide when to substitute a ghost.
  • a top-level Ghost-class window titled for Fusion - corroboration that survives a racy probe.

A hung host now returns a different error entirely:

errorCode: "fusion_host_hung"
hungSignals: ["IsHungAppWindow", "GhostWindow"]
restartAttempted: true
_hint: "Do NOT hunt for a blocking dialog - there is not one. Nothing reaches Fusion
        over IPC while the host is hung. The bridge force-restarted it; poll
        fusion_readiness."

and the add-in case now says hostResponding: true so the two are distinguishable without reading prose.

Per the automation doctrine the bridge does not just classify it - it force-restarts (straight to kill + start, since a hung process will not close politely). You should not have had to restart Fusion by hand to keep your matrix moving.

The _hint you quoted is not ours

Worth chasing where it lives, because it is still wrong for the next person:

"Auto-dismiss was attempted but could not clear all blocking dialogs.
 Check _dismissResult.remaining[] - each has a screenshotPath."

That string appears nowhere in this repo - no hit in server.py, the add-in, or the handlers. Neither does _dismissResult. Our own not-responding hints only ever talk about restarting Fusion; none of them mention dialogs. So this is ab-side text, same shape as dialogsDismissed from #86. Since it asserts a remaining[] array that was empty, it is worth fixing at the source - and ideally gating the sentence on remaining actually being non-empty, because "auto-dismiss could not clear all dialogs" with zero dialogs is the exact wrong-tree signal that cost you the minutes.

On the hang itself

Your context says it hung on the FIRST part of a 10-part matrix with the demo's own staged component unsaved. That is our part to own, and I would rather chase it than shrug at "Fusion hung". If the restart got your matrix moving, please post whatever it measured - a hang on part 1 of 10 that does not recur is a different bug from one that recurs at the same step, and the results tell me which.

Closing since the reporting defect is fixed; reopen if the hang itself repeats and I will dig into what the surfaces are doing to it.

John Lauer closed this · 2mo ago

Log in to reply.