Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ghidra connection to lldb: Timeout with larger binary #7866

Open
develorer opened this issue Feb 27, 2025 · 11 comments
Open

Ghidra connection to lldb: Timeout with larger binary #7866

develorer opened this issue Feb 27, 2025 · 11 comments
Labels
Feature: Debugger Status: Internal This is being tracked internally by the Ghidra team

Comments

@develorer
Copy link

Describe the bug
When I launch a binary with lldb and it tries to connect to ghidra, it fails with a java.net.SocketTimeoutException

To Reproduce
Steps to reproduce the behavior:

  1. Right click on somewhat large binary in the project window
  2. Select debugger
  3. Configure and Launch debugger, choose lldb.
  4. It opens the terminal window, runs "version", then "script import ghidralldb", then "target create $BINARYPATH"
  5. The error shows up because lldb hasn't finished processing "target create", and did not have time to move on to "ghidra trace connect" and "ghidra trace start" before ghidra got impatient and timedout

Expected behavior
I would expect ghidra to wait longer, and attach correctly to lldb.

Environment (please complete the following information):

  • OS: macOS 10.15.
  • Java Version: 21.0.6
  • Ghidra Version: 11.3.1
  • Ghidra Origin: official GitHub distro

Additional context
The timeout happens inside ghidra.app.plugin.core.debug.service.tracermi.AbstractTraceRmiListener.doAccept (line 66).

When I try the same thing with a smaller binary, "target create" takes less time, and things work correctly.
The file "local-lldb.sh" shows clearly the steps, and we would need to have completed "target create" sooner, to reach "ghidra trace connect" and "ghidra trace start" before the ghidra java times out.

Note that when I try this on a faster machine, I also don't have a problem (for the same reason).

Does anyone have an idea for a quick fix for this? It would seem I just need to set a longer timeout parameter for the "DefaultTraceRmiAcceptor.accept" function, but can I do that without recompiling ghidra?

Thanks!

@d-millar
Copy link
Collaborator

@develorer Just say "Keep", the timeout doesn't really do anything - mostly a warning that something may have gone wrong. (We do have ticket in for making the timeout configurable, but....)

@develorer
Copy link
Author

Unfortunately when the timeout shows up, the connection closes (in the "Connections" window). And so the next command in the lldb terminal "ghidra trace connect "127.0.0.1:49252" fails with the error message "Connection refused", which makes sense since the connection was closed on Ghidra's side. So I cannot just ignore it.

@d-millar
Copy link
Collaborator

OK, so this is an actual error, i.e. if the connection closes, the connection failed (vs. timed out). Can you connect to the same target using lldb from a shell? With lldb, my first guess is always lack of permissions, so would like to rule that out.

@develorer
Copy link
Author

Yes, I can connect the same target from a shell.

@d-millar
Copy link
Collaborator

d-millar commented Feb 28, 2025

OK. Just running a few tests here for comparison, looks like failure on permissions would have happened after the "target create". Are there connections open in the Connections window? Generally, you're going to want to "Close All" before starting another. (We intend to support this, but right now it has issues.) Any messages in the "Debug Console" window that seem helpful and/or in the terminal if you start Ghidra using "support/ghidraDebug" instead of "ghidraRun"?

@develorer
Copy link
Author

develorer commented Feb 28, 2025

Thanks a lot for looking into it.

There are no connections open before I click on the bug icon to launch the debugging process.

  1. Right after I click on the bug icon, a connection is created, as expected.
  2. The Debug Console shows "Waiting for connection (task 3 of 6) and ends up being replaced by "Launch lldb failed". During this, the terminal is open and still working on the line "target create $BINPATH".
  3. The pop up with the java timeout of "accept" appears. The connection disappears from the "Connections" window.
  4. After that, lldb inside the terminal finished creating the target, it moves to the next line "ghidra trace connect "127.0.0.1:49232" and fails there because the ghidra server is closed.

In the Debug Console the detailed error message is this:

Accept timed out java.net.SocketTimeoutException: Accept timed out
	at java.base/sun.nio.ch.NioSocketImpl.timedAccept (NioSocketImpl-java:701)
	at java.base/sun.nio.ch.NioSocketImpl.accept(NioSocketImpl.java:745)
	at java.base/java.net.ServerSocket. implAccept(ServerSocket.jawa:698)
	at java.base/java.net.ServerSocket.platformImplAccept(ServerSocket.java:663)
	at java.base/java.net.ServerSocket. implAccept(ServerSocket.java:639)
	at java.base/java.net.ServerSocket. implAccept(ServerSocket.java:585)
	at java.base/java.net.ServerSocket.accept(ServerSocket.java:543)
	at ghidra.app.plugin.core.debug.service.tracemmi.AbstractTraceRmiListener.doAccept(AbstractTraceRmiListener.java:66)
	at ghidra.app.plugin.core.debug.service.tracermf.DefaultTraceRmiAcceptor.accept(DefaultTraceRmiAcceptor.java:51)
	at ghidra.app.plugin. core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.launchProgram(AbstractTraceRmiLaunchOffer.java:658)
	at ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRniLauncherServicePlugin$ConfigureAndLaunchTask. run(TraceRmiLauncherServicePlugin-java:128)
	at ghidra.app.services.ProgressService.lambda$execute$0(ProgressService.java:123)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java: 1768)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java: 1760)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool. java:1843)
	at java.base/java.util.concurrent.ForkJoinPool. runWorker(ForkJoinPool. java:1808) at java.base/java.util.concurrent.ForkJoinWorkerThread. run(ForkJoinWorkerThread.java:188)

I am unable to try the "support/ghidraDebug" right now. I will when I can.

However, to me it seems like a very simple Timeout. It seems the java code of ghidra waits for the connection and fails when it does not receive it soon. lldb only makes that connection when it does "ghidra trace connect", which it does only after "target create"

I have thoroughly tested everything else, and all the "ghidra trace connect/start/sync-enabl" work perfectly fine. They can all connect fine in any case where the target create does not take too much time. This is unrelated to the binary path itself, only the size of the binary.

@d-millar
Copy link
Collaborator

OK, looking into it.... Your original post said you didn't make it to "ghidra trace connect", so was a little thrown off.

@develorer
Copy link
Author

Sorry for the confusion, when I said lldb "did not have time to move on to ghidra trace connect and ghidra trace start before ghidra got impatient and timedout", I meant that lldb still reached the ghidra trace connect, but not in time.

@d-millar
Copy link
Collaborator

Yep, no problem - just didn't want you to think I was ignoring what you were saying.

OK, going through the code, looks like no easy answer. :(

I will put in a ticket for this - we may already have one, but, if so, will bump the priority. In the meantime, wrt workarounds, I think you have two options:
(1) use the remote-lldb.sh launcher to connect to the target after it has been launched, or
(2) modify the DEFAULT_TIMEOUT_MILLIS to something greater than 10s

I realize building Ghidra from scratch is probably not your idea of how to spend a Friday, but the instructions on the website are pretty good and relatively self-explanatory.

@develorer
Copy link
Author

Thanks, I appreciate it!

I am looking forward to a more permanent fix, but will work with the workarounds you suggested in the meantime. They do make sense.

I have to say I am super impressed by the quality of the tool and the support. It's exceptional to receive quality answers in such a short amount of time. Thanks a lot!

@d-millar
Copy link
Collaborator

Thanks - really appreciate the thumb up and your willingness to contribute and help us make a better product!

@d-millar d-millar added the Status: Internal This is being tracked internally by the Ghidra team label Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Debugger Status: Internal This is being tracked internally by the Ghidra team
Projects
None yet
Development

No branches or pull requests

2 participants