NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
50.86k stars 5.8k forks source link

Most of GUI No Longer Responds to Keyboard Input #3208

Closed foreverWIP closed 1 week ago

foreverWIP commented 3 years ago

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:

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.

dragonmacher commented 3 years ago

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.

foreverWIP commented 3 years ago

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.

dragonmacher commented 3 years ago

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:

foreverWIP commented 3 years ago

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

foreverWIP commented 3 years ago

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.

gipi commented 2 years ago

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.

madebr commented 1 year ago

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

mumbel commented 1 year ago

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

SchrodingersMind commented 1 year ago

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

tonybounty commented 11 months ago

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.

madebr commented 11 months ago

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.

PJ-Zetier commented 2 weeks ago

I also experience this randomly, like right now.. Any insight into what may be causing this? The only thing i can think of that may be causing it is a builtin java hotkey combo that may disable keyboard input in the jvm...

ryanmkurtz commented 1 week ago

It sounds like this is a duplicate of #5085. Try clearing your clipboard.