shmemBase_attach failed when connecting to Android

2019-02-20 21:00发布

I'm trying to hook up jdb on my computer to a process (any process really) on my Android device, but it doesn't work at all.

So the commands I used are straight off the Google ADB Documentation. First I do

adb forward tcp:3456 jdwp:pid

Then after that I try to use jdb to try to hook up

jdb -attach emulatorIP:3456

But I get the following error:

java.io.IOException: shmemBase_attach failed: The system cannot find the file specified

    at com.sun.tools.jdi.SharedMemoryTransportService.attach0(Native Method)
    at com.sun.tools.jdi.SharedMemoryTransportService.attach(SharedMemoryTransportService.java:108)
    at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116)
    at com.sun.tools.jdi.SharedMemoryAttachingConnector.attach(SharedMemoryAttachingConnector.java:63)
    at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
    at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
    at com.sun.tools.example.debug.tty.Env.init(Env.java:63)
    at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1066)

Fatal error: 
Unable to attach to target VM.

EDIT: I have more leads, but I'm nowhere close to an actual solution.

JDB -attach for some reason defaults to debugging using the shared memory method despite all documentation insisting that specifying hostname:port as the -attach parameters will force it to use sockets for remote debugging. To force it, you use the command provided by ykw's answer, but it fails anyway ostensibly due to some connection error.

After further investigation it appears that JDB and ADB conflict with each other on some unknown resource causing the various socket connection errors. My current workaround is to shut down ADB completely and run JDB, then when I'm done with the JDB, I get the ADB back online. Not acceptable by any means and I'm hoping this helps someone with a more in-depth knowledge pinpoint what's wrong!

标签: android jdb
2条回答
\"骚年 ilove
2楼-- · 2019-02-20 21:26

You can try entering this command:

jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=3456

Theoretically, you should get the following output:

Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>

However, I got the following:

java.io.IOException: handshake failed - connection prematurally closed
        at com.sun.tools.jdi.SocketTransportService.handshake(SocketTransportService.java:136)
        at com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:232)
        at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116)
        at com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:90)
        at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
        at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
        at com.sun.tools.example.debug.tty.Env.init(Env.java:63)
        at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1066)

Does anyone know why this is happening?

Ok... The above problem has been resolved. This is due to a conflict between adb calls. There should only be 1 adb instance running at any point in time. This will occur when jdb tries to connect while adb is already running in your program. jdb will never be able to attach successfully in this state.

The TLDR version would be to just key in the command at the top of this answer and you will get the expected output.

查看更多
\"骚年 ilove
3楼-- · 2019-02-20 21:28

Try quitting Android Studio.

Its ADB is running even when your project is not. Here is an example where I quit Android Studio, ran ADB, launched my app within the device, then ran ADB again to see the new process id, forwarded the port and finally attached JDB:

$ adb -d jdwp
* daemon not running. starting it now at tcp:5037 *
* daemon started successfully *
28462
^C
$ adb -d jdwp
28462
1939
^C
$ adb -d forward tcp:7777 jdwp:1939
$ jdb -attach localhost:7777 -sourcepath ./src
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
> 

You can also turn ADB on and off within Android Studio:

Android Studio->Tools->Android->Enable ADB Integration

When ADB integration is disabled, you can run ADB from the console as usual. You can also control and background ADB daemons with:

adb kill-server
adb start-server

I wasted a couple of hours on this, so it really needs better documentation. Also I would like to know how to run both the Android Studio debugger and JDB at the same time so that I can profile all method calls while stepping through the debugger (because the built-in Android Studio monitor tracing doesn't show consecutive method calls with arguments):

http://mybrainoncode.com/blog/2013/11/03/debugging-android-with-jdb/

https://teaspoon-consulting.com/articles/tracing-java-method-calls.html

查看更多
登录 后发表回答