ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

Most of GUI No Longer Responds to Keyboard Input

Open foreverWIP opened this issue 3 years ago • 8 comments

Describe the bug When entering text into a text field in the CodeBrowser, occasionally most of the the GUI (including the CodeBrowser window and the main project window) will no longer react to any keystrokes, whether it's a text field that's selected for input, or general shortcuts like Ctrl+S for saving. The only parts that still respond to keystrokes are the Console window and all "rich text" widgets (like the bottom of the Script Manager that displays information about a selected script, as well as the right-hand side of the Help window that displays the page contents). The only way to "fix" the issue is restarting Ghidra. While I can't pinpoint a specific case of the issue occurring, it tends to happen more often when either switching windows (Alt+Tab) immediately before/after/while entering text, or while entering text in the data type chooser (most often in the structure editor, but has happened in the listing display as well).

To Reproduce I can't yet find a specific way to trigger the bug every time, but a general example of how it occurs goes as follows:

  1. Start Ghidra and open a file with the CodeBrowser.
  2. Open the structure editor (either by creating a new structure in the Data Type Manager, or opening an existing one).
  3. Start defining components in the structure, frequently switching between the window the structure editor is in and another window, especially while entering the type into the DataType column.
  4. Eventually the GUI will no longer react to keystrokes.

Expected behavior The GUI still reacts to keyboard input, for text entry and shortcuts, even after repeatedly gaining and losing focus.

Attachments Thread dump taken from jstack

Environment:

  • OS: Kubuntu 21.04, unmodified kernel
  • Java Version: OpenJDK 11.0.11, Oracle JDK 11.0.11
  • Ghidra Version: 10.0
  • Ghidra Origin: Official GitHub release

Additional context Mouse input continues to be handled after the bug occurs. The issue also occurs when running support/ghidraDebug, and nothing about the issue is logged there. Configuring focus stealing prevention in Plasma settings does not prevent the issue. The closest related issue I could find is #1516, and while the source of the bug may not be the same, the way the GUI stops responding here makes me think it could be a threading issue, or keyboard focus from one GUI window not properly switched upon closing (the GUI for the data type completion occasionally shows up as generic X11 windows in my taskbar, so I feel like that might be related as well). I will update this report if I find a more consistent way of triggering the bug.

foreverWIP avatar Jul 12 '21 01:07 foreverWIP

Obviously, without us being able to reproduce the issue, this will be tough to diagnose.

This sounds different to me than the ticket you mentioned above. That ticket is dealing with a lockup of the entire UI. If I read your info correctly, Ghidra still works for you, other than the keyboard input? The UI still paints and your mouse actions still work, I'm assuming.

We have seen in the past on different versions of Linux the issue of keyboard input not working. That has typically been an issue of a focus handshake between the main UI and temporary dialogs (potentially the data type chooser in you case). In the past, you were able to sometimes fix the issue by using another text field inside of a modal dialog after the tool gets into this state. So, to try this, the next time you find the tool in this state, try using a text field inside of a modal dialog. For example, in the bad state, go to the menu bar with the mouse and press Navigation -> Go To... and see if you can type in the text field in that dialog.

As you mentioned, this could be related to the text field that appears inside of the structure editor. Along the same lines as above, you can try to edit a structure data type from within the structure editor when the tool gets into this state. The hope here would be that by using again the data type chooser from the structure editor may reset the focus owner state of the system.

My guess with all this is that the focus owner gets lost during Alt-Tab usage while the focus is in a transient Ghidra widget, such as a temporary editor (like the Data Type Editor in the Structure Editor) or in a text field within a modal dialog.

dragonmacher avatar Jul 12 '21 14:07 dragonmacher

I've meant to respond the next time I encountered the issue, and only just now has it happened again, so apologies for any wait.

I want to confirm that the all mouse interaction does still work across all open windows; I can click, right-click, drag, etc. While typing this response I tried making the bug occur multiple times to get a better idea of what was happening, and while I still haven't found a consistent way to cause it, I've found that it's also happened in both the Function Editor window (after using the type chooser) and Storage Address Editor window (this time after using the keyboard to select something in a dropdown menu in the Location column). Attempting to reset the bad state with other modal windows (Go To, Search Memory, etc.) does not work, nor does reopening the same window and input field.

foreverWIP avatar Jul 15 '21 01:07 foreverWIP

Attempting to reset the bad state with other modal windows (Go To, Search Memory, etc.) does not work, nor does reopening the same window and input field.

Thanks for the update. It seems specifically related to the table editing. At this point in time I cannot reproduce the issue, which makes it hard to find a workaround.

The issue is likely related to your OS and it's focus subsystem. In the past users have had some success tweaking the OS settings to work around issues such as this. Further, usually when I have seen this type of bug, it tends to go away as the version of Linux gets updated over time.

I was unable to find any bug tickets related to this issue. As is common with Linux users, some experimentation may help you identify and fix the issue. Some things to try:

  • Using a different Java 11 vm implementation
  • Changing the window manager used by your Kubuntu
  • Trying a different version of Kubunu
  • Trying a different Linux distrubution

dragonmacher avatar Jul 15 '21 14:07 dragonmacher

I've been testing running Ghidra in different environments and configurations, so far I've tried the following:

  • Modifying focus stealing prevention: KDE Plasma has options to control whether a window's focus can be taken by other windows without the user explicitly switching to them. The bug still occurs regardless of how it's set.
  • Using Oracle JDK 11: The bug also still occurs under this VM.
  • Running Manjaro Linux with XFCE in a virtual machine (as I don't have another desktop system to run it directly on): I haven't experienced an issue here yet, but I will provide an update if I do. I also plan to set up other VM's for different distro/window manager combinations to test on if I don't run into the issue on the Manjaro VM soon.

foreverWIP avatar Jul 17 '21 05:07 foreverWIP

So far I've tested multiple VM's: Manjaro Linux with XFCE and KDE, and normal Ubuntu, and I haven't encountered the issue in any of them. Today I thought I could use a script to track down the issue (by printing information from java.awt.KeyboardFocusManager; I've barely used Java before so forgive me if I'm looking in the wrong place!). While I haven't yet been able to narrow it down with the script, in the process of testing it I did find an interesting quirk about the UI state after the bug occured.

While most of the UI is unresponsive to keyboard input, I found a few elements that still respond, namely the Console window where script output is printed, and all "rich text" widgets, i.e. the bottom of the Script Manager that displays information about a selected script, as well as the right-hand side of the Help window that displays the page contents. All keyboard input was handled as expected, even shortcuts. For example, I've been able to use shortcuts in the CodeBrowser window by docking the Console window in it, focusing the Console window, and inputting the hotkey.

Since there are indeed parts of the UI that still respond to keyboard input, this makes me think it might not be a problem with my system configuration or distribution. I don't know how much the quirk in the bugged state helps in identifying the exact source of the issue, but at least it gives a good indication that it's coming from within Ghidra.

I'll experiment with scripting more and update when I find any other notable information.

foreverWIP avatar Jul 23 '21 04:07 foreverWIP

comment to report that I experienced the same problem: it happens randomly, sometimes more the once in a day, sometimes for a week all work normally. I'm using Debian with gnome as destkop manager, ghidra version 10.1.4.

gipi avatar Jun 30 '22 13:06 gipi

This issue also started happening on my system since updating to latest Ghidra 10.3, and to the latest Fedora release. Today, I was finally able to create a reproducer that has a similar behavior.

I don't think my reproducer is the same as initially reported in this thread because it can be "fixed" by temporarily going to another program, typing something there, and finally switching back to Ghidra. Nonetheless, I hope it's useful.

Reproducer steps:

  1. Open the "code browser" tool, with a project open
  2. Start editing a new struct by right clicking on the program name in the "Data Type Manager", and clicking on "New >" and "Struct..."
  3. Inside the "Structure editor", add a new unnamed int by typing "int" in the "DataType" column, and press ENTER.
  4. Select the just created struct item member by clicking on it once
  5. Click on the button in the "Structure Editor" toolbar with help text "Create a new structure from the selected components and replace them with it."
  6. A message box should show up, warning us that only a single member has been selected.
  7. Press "No" to cancel creating the new struct

While investigating, I got the following Java backtrace: (I don't know how I caused it, but is very similar to the steps above)

Java backtrace
Cannot invoke "javax.swing.table.TableColumn.getModelIndex()" because the return value of "javax.swing.table.TableColumnModel.getColumn(int)" is null
java.lang.NullPointerException: Cannot invoke "javax.swing.table.TableColumn.getModelIndex()" because the return value of "javax.swing.table.TableColumnModel.getColumn(int)" is null
	at java.desktop/sun.swing.SwingUtilities2.convertColumnIndexToModel(SwingUtilities2.java:2156)
	at java.desktop/javax.swing.JTable.convertColumnIndexToModel(JTable.java:2626)
	at java.desktop/javax.swing.JTable.setValueAt(JTable.java:2788)
	at java.desktop/javax.swing.JTable.editingStopped(JTable.java:4785)
	at java.desktop/javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:152)
	at ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$ComponentNameCellEditor.stopCellEditing(CompositeEditorPanel.java:1228)
	at ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel.stopCellEditing(CompositeEditorPanel.java:237)
	at ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel.endFieldEditing(CompositeEditorPanel.java:1042)
	at ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$ComponentStringCellEditor$1.focusLost(CompositeEditorPanel.java:1173)
	at java.desktop/java.awt.AWTEventMulticaster.focusLost(AWTEventMulticaster.java:238)
	at java.desktop/java.awt.Component.processFocusEvent(Component.java:6512)
	at java.desktop/java.awt.Component.processEvent(Component.java:6376)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4995)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1070)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:738)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4876)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:117)
	at java.desktop/java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:191)
	at java.desktop/java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:236)
	at java.desktop/java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:234)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:319)
	at java.desktop/java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:234)
	at java.desktop/java.awt.Dialog.show(Dialog.java:1080)
	at java.desktop/java.awt.Component.show(Component.java:1728)
	at java.desktop/java.awt.Component.setVisible(Component.java:1675)
	at java.desktop/java.awt.Window.setVisible(Window.java:1036)
	at java.desktop/java.awt.Dialog.setVisible(Dialog.java:1016)
	at docking.DockingDialog.setVisible(DockingDialog.java:353)
	at docking.DockingWindowManager.lambda$doShowDialog$6(DockingWindowManager.java:1769)
	at ghidra.util.Swing.doRun(Swing.java:292)
	at ghidra.util.Swing.runNow(Swing.java:208)
	at ghidra.util.Swing.runNow(Swing.java:163)
	at docking.DockingWindowManager.doShowDialog(DockingWindowManager.java:1773)
	at docking.DockingWindowManager.showDialog(DockingWindowManager.java:1722)
	at docking.widgets.OptionDialog.show(OptionDialog.java:432)
	at docking.widgets.OptionDialog.lambda$showOptionDialog$7(OptionDialog.java:683)
	at ghidra.util.Swing.lambda$runNow$1(Swing.java:148)
	at ghidra.util.Swing.doRun(Swing.java:292)
	at ghidra.util.Swing.runNow(Swing.java:208)
	at ghidra.util.Swing.runNow(Swing.java:163)
	at ghidra.util.Swing.runNow(Swing.java:148)
	at docking.widgets.OptionDialog.showOptionDialog(OptionDialog.java:680)
	at ghidra.app.plugin.core.progmgr.ProgramSaveManager.handleChangedProgram(ProgramSaveManager.java:291)
	at ghidra.app.plugin.core.progmgr.ProgramSaveManager.canClose(ProgramSaveManager.java:75)
	at ghidra.app.plugin.core.progmgr.ProgramSaveManager.saveChangedPrograms(ProgramSaveManager.java:193)
	at ghidra.app.plugin.core.progmgr.ProgramSaveManager.canCloseAll(ProgramSaveManager.java:108)
	at ghidra.app.plugin.core.progmgr.ProgramManagerPlugin.saveData(ProgramManagerPlugin.java:475)
	at ghidra.framework.plugintool.PluginManager.saveData(PluginManager.java:648)
	at ghidra.framework.plugintool.PluginTool.close(PluginTool.java:1142)
	at ghidra.framework.plugintool.PluginTool.close(PluginTool.java:1138)
	at docking.DockingWindowManager.close(DockingWindowManager.java:1132)
	at docking.RootNode$JFrameWindowWrapper$1.windowClosing(RootNode.java:744)
	at java.desktop/java.awt.AWTEventMulticaster.windowClosing(AWTEventMulticaster.java:357)
	at java.desktop/java.awt.AWTEventMulticaster.windowClosing(AWTEventMulticaster.java:357)
	at java.desktop/java.awt.Window.processWindowEvent(Window.java:2085)
	at java.desktop/javax.swing.JFrame.processWindowEvent(JFrame.java:298)
	at java.desktop/java.awt.Window.processEvent(Window.java:2044)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4995)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

---------------------------------------------------
Build Date: 2023-May-10 1508 EDT
Ghidra Version: 10.3
Java Home: /usr/lib/jvm/java-20-openjdk-20.0.1.0.9-8.rolling.fc38.x86_64
JVM Version: Red Hat, Inc. 20.0.1
OS: Linux 6.3.5-200.fc38.x86_64 amd64
Workstation: fedora

System: Ghidra 10.3 Fedora Linux 38 OpenJDK 20.0.1

madebr avatar Jun 13 '23 01:06 madebr

I've noticed this and think it was when I went from 20.04 to 22.04 recently . not if 10.2.x->10.3 related though

I start ghidraRun on terminal and open a program and keystrokes def work. Then for whatever reason ghidra stops receiving keystrokes and if I tab back to terminal (in ghidra background) there are a ton of ts from me trying to to type a global. Clicking in another box like the python (docked with console/bookmarks) I can then typecast globals again

mumbel avatar Jun 14 '23 21:06 mumbel

I have similar issues on Lubuntu 22.04. My system has two keyboard layouts: Ukrainian(default) and English. And when I try to change shortcuts in key bindings menu, most of the characters are printed as non-ascii (doesn't matter which system-wide layout is selected) ghidra_bug

Except for space and comma keys ghidra_bug_space ghidra_bug_comma

Also, key with comma in English layout correspond to period character in Ukrainian layout. All rich-text fields works as intended. So, I think Ghidra isn't using system language preferences for key bindings and (in my case from the start) switches to default layout

SchrodingersMind avatar Sep 01 '23 08:09 SchrodingersMind

I have the same problem with Ghidra 10.4 on Ubuntu 23.04. This rarely happens and this is completely random, so I can't explain how to reproduce it. Today, for example, I resumed my Linux OS with 2 projects Ghidra opened, one of them is completely unresponsive to my keyboard whereas the other works normally. I tried to keystroke in lots of different fields: open dialog box, filter, listing, decompiler, keybinding settings, Go To box, in project window... The only solution is to restart Ghidra.

tonybounty avatar Nov 05 '23 11:11 tonybounty

Could this issue be related to Wayland, or at least be triggered more easily? It looks like commenters on this issue (including me) use a recent distro with a Wayland compositor. Colleagues of me, using x11 have never encountered this issue.

madebr avatar Nov 05 '23 11:11 madebr