Fixed
Status Update
Comments
rm...@google.com <rm...@google.com> #2
Thank you for your feedback. Team may reach out for more feedback in reproducing or triaging this issue.
vs...@google.com <vs...@google.com> #3
arifs/enh/dan: Could you guys triage this as appropriate? The stackoverflow link in comment #1 has more details.
en...@google.com <en...@google.com> #4
i think yabinc knows that code the best...
af...@gmail.com <af...@gmail.com> #5
That stackoverflow link in comment#1 is mine and is the result of spending 2-3 days in android source(even though I may have gotten it wrong).
But posting all details here is hard without any good way of formatting it. So I posted how problem appear with some sample code here and left other details in stackoverflow.
I addition I found this bug too in bugtracker and I think they are probably related:
https://issuetracker.google.com/issues/109505014
But posting all details here is hard without any good way of formatting it. So I posted how problem appear with some sample code here and left other details in stackoverflow.
I addition I found this bug too in bugtracker and I think they are probably related:
ya...@google.com <ya...@google.com> #6
My progress so far is below:
adb jdwp doesn't export the app process. Because the debuggable flag isn't added when running app_process through wrap.sh. It can be work around by adding the debuggable option in wrap.sh as below:
def writeWrapScript(wrapFile) {
wrapFile.withWriter { writer ->
writer.write('#!/system/bin/sh\n')
writer.write('name=\$1\n')
writer.write('shift\n')
//writer.write('\$name -XjdwpProvider:adbconnection \$@\n')
//writer.write('\$name -XjdwpProvider:default \$@\n')
writer.write('\$name -Xcompiler-option --debuggable \$@\n')
}
}
after doing it, adb jdwp exports the app process. But Android studio still can't debug the app process. I will look into it.
adb jdwp doesn't export the app process. Because the debuggable flag isn't added when running app_process through wrap.sh. It can be work around by adding the debuggable option in wrap.sh as below:
def writeWrapScript(wrapFile) {
wrapFile.withWriter { writer ->
writer.write('#!/system/bin/sh\n')
writer.write('name=\$1\n')
writer.write('shift\n')
//writer.write('\$name -XjdwpProvider:adbconnection \$@\n')
//writer.write('\$name -XjdwpProvider:default \$@\n')
writer.write('\$name -Xcompiler-option --debuggable \$@\n')
}
}
after doing it, adb jdwp exports the app process. But Android studio still can't debug the app process. I will look into it.
al...@google.com <al...@google.com> #7
NB For P (and only P, we fixed it for Q and <= O had a different debugger) you need to add -XjdwpOptions:suspend=n,server=y to have the java debugger actually come up.
These (theoretically default) arguments are explicitly passed in by AndroidRuntime.cpp for normal startups and adbconnection had a bug where it would not insert them into the argument string correctly if they were not specified directly. (https://android-review.googlesource.com/c/platform/art/+/702364/ https://issuetracker.google.com/issues/109505014#comment11 )
Try with:
writer.write('\$name -Xcompiler-option --debuggable -XjdwpOptions:suspend=n,server=y \$@\n')
These (theoretically default) arguments are explicitly passed in by AndroidRuntime.cpp for normal startups and adbconnection had a bug where it would not insert them into the argument string correctly if they were not specified directly. (
Try with:
writer.write('\$name -Xcompiler-option --debuggable -XjdwpOptions:suspend=n,server=y \$@\n')
af...@gmail.com <af...@gmail.com> #8
Hurray!!!!
Finally with help for comment#6 and comment#7 , I were able to get this work on android P (api level 28) AND android O 8.1 (api level 27) emulator. We need following code:
wrapFile.withWriter { writer ->
writer.write('#!/system/bin/sh\n')
writer.write('processname=\$1\n')
writer.write('sdkversion=\$(getprop ro.build.version.sdk)\n')
writer.write('if [ "\$sdkversion" -gt "28" ]; then\n')
writer.write('fullpath="\$@"\n')
writer.write('elif [ "\$sdkversion" -eq "28" ]; then\n')
writer.write('shift 3\n')
writer.write('fullpath="\$processname -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable \$@"\n')
writer.write('elif [ "\$sdkversion" -eq "27" ]; then\n')
writer.write('shift\n')
writer.write('fullpath="\$processname -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable \$@"\n')
writer.write('else\n')
writer.write('log -p e -t "WRAPPER" "Wrapper script only works starting API level 27!"\n')
writer.write('exit 1\n')
writer.write('fi\n')
writer.write('\$fullpath\n')
}
Why we need this code?
1-api level 27 is missing some options for running in debug mode.
2-api level 28 is missing some options and is passing incorrect --generate-mini-debug-info option which prevent running correctly. I used `shift 3` to remove '-Xcompiler-option --generate-mini-debug-info' from generated command line.
3- I have considered starting android Q everything works. so I use command line. cannot test this myself.
Anyway thanks for help. I will update stackoverflow thread for other people too. :)
BTW, it will great if someone can update wrap.sh page at:
https://developer.android.com/ndk/guides/wrap-script
to link to this thread or my stackoverflow thread at:
https://stackoverflow.com/questions/54550668/cannot-debug-app-when-using-wrapper-script
It will save a lot of time for other people.
Finally with help for
wrapFile.withWriter { writer ->
writer.write('#!/system/bin/sh\n')
writer.write('processname=\$1\n')
writer.write('sdkversion=\$(getprop ro.build.version.sdk)\n')
writer.write('if [ "\$sdkversion" -gt "28" ]; then\n')
writer.write('fullpath="\$@"\n')
writer.write('elif [ "\$sdkversion" -eq "28" ]; then\n')
writer.write('shift 3\n')
writer.write('fullpath="\$processname -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable \$@"\n')
writer.write('elif [ "\$sdkversion" -eq "27" ]; then\n')
writer.write('shift\n')
writer.write('fullpath="\$processname -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable \$@"\n')
writer.write('else\n')
writer.write('log -p e -t "WRAPPER" "Wrapper script only works starting API level 27!"\n')
writer.write('exit 1\n')
writer.write('fi\n')
writer.write('\$fullpath\n')
}
Why we need this code?
1-api level 27 is missing some options for running in debug mode.
2-api level 28 is missing some options and is passing incorrect --generate-mini-debug-info option which prevent running correctly. I used `shift 3` to remove '-Xcompiler-option --generate-mini-debug-info' from generated command line.
3- I have considered starting android Q everything works. so I use command line. cannot test this myself.
Anyway thanks for help. I will update stackoverflow thread for other people too. :)
BTW, it will great if someone can update wrap.sh page at:
to link to this thread or my stackoverflow thread at:
It will save a lot of time for other people.
ya...@google.com <ya...@google.com> #9
For android P, I verified the script in comment #8 works. But it also works without removing -Xcompiler-option --generate-mini-debug-info option. Can you specific how --generate-mini-debug-info prevents running correctly?
I tested on android Q, but haven't found option to make it work (I have tried all combinations of -XjdwpProvider:adbconnection, -XjdwpOptions:suspend=n,server=y and -Xcompiler-option --debuggable).
I get following two exception in Android Studio:
Java debugger detached or detaching
com.intellij.execution.ExecutionException: Java debugger detached or detaching
at com.android.tools.ndk.run.jdwp.JdwpConnector.waitForAttach(JdwpConnector.java:351)
at com.android.tools.ndk.run.jdwp.JdwpConnector.Connect(JdwpConnector.java:377)
at com.android.tools.ndk.run.lldb.SessionStarter.sessionStarted(SessionStarter.java:256)
at com.android.tools.ndk.run.AndroidNativeAppDebugProcess.doStartTarget(AndroidNativeAppDebugProcess.java:450)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess.lambda$sessionInitialized$2(CidrDebugProcess.java:435)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess$VoidDebuggerCommand.call(CidrDebugProcess.java:658)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess$VoidDebuggerCommand.call(CidrDebugProcess.java:652)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess.lambda$postCommand$9(CidrDebugProcess.java:536)
at com.jetbrains.cidr.execution.ExecutionQueueProcessor.lambda$runAsync$0(ExecutionQueueProcessor.java:26)
at com.jetbrains.cidr.execution.ExecutionQueueProcessor.lambda$runAsync$1(ExecutionQueueProcessor.java:36)
at com.intellij.util.concurrency.QueueProcessor$RunnableConsumer.consume(QueueProcessor.java:280)
at com.intellij.util.concurrency.QueueProcessor$RunnableConsumer.consume(QueueProcessor.java:277)
at com.intellij.util.concurrency.QueueProcessor.lambda$null$0(QueueProcessor.java:79)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:232)
at com.intellij.util.concurrency.QueueProcessor.lambda$wrappingProcessor$1(QueueProcessor.java:79)
at com.intellij.util.concurrency.QueueProcessor.lambda$null$3(QueueProcessor.java:212)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:232)
at com.intellij.util.concurrency.QueueProcessor.lambda$startProcessing$4(QueueProcessor.java:212)
at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
java.lang.NullPointerException
at com.android.tools.idea.run.GradleApplicationIdProvider.getTestPackageName(GradleApplicationIdProvider.java:122)
at com.android.tools.idea.run.AndroidLaunchTasksProvider.getConnectDebuggerTask(AndroidLaunchTasksProvider.java:225)
at com.android.tools.idea.run.LaunchTaskRunner.run(LaunchTaskRunner.java:85)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:736)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:580)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:525)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:85)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
at com.intellij.openapi.progress.impl.CoreProgressManager$4.run(CoreProgressManager.java:395)
at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
I tested on android Q, but haven't found option to make it work (I have tried all combinations of -XjdwpProvider:adbconnection, -XjdwpOptions:suspend=n,server=y and -Xcompiler-option --debuggable).
I get following two exception in Android Studio:
Java debugger detached or detaching
com.intellij.execution.ExecutionException: Java debugger detached or detaching
at com.android.tools.ndk.run.jdwp.JdwpConnector.waitForAttach(JdwpConnector.java:351)
at com.android.tools.ndk.run.jdwp.JdwpConnector.Connect(JdwpConnector.java:377)
at com.android.tools.ndk.run.lldb.SessionStarter.sessionStarted(SessionStarter.java:256)
at com.android.tools.ndk.run.AndroidNativeAppDebugProcess.doStartTarget(AndroidNativeAppDebugProcess.java:450)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess.lambda$sessionInitialized$2(CidrDebugProcess.java:435)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess$VoidDebuggerCommand.call(CidrDebugProcess.java:658)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess$VoidDebuggerCommand.call(CidrDebugProcess.java:652)
at com.jetbrains.cidr.execution.debugger.CidrDebugProcess.lambda$postCommand$9(CidrDebugProcess.java:536)
at com.jetbrains.cidr.execution.ExecutionQueueProcessor.lambda$runAsync$0(ExecutionQueueProcessor.java:26)
at com.jetbrains.cidr.execution.ExecutionQueueProcessor.lambda$runAsync$1(ExecutionQueueProcessor.java:36)
at com.intellij.util.concurrency.QueueProcessor$RunnableConsumer.consume(QueueProcessor.java:280)
at com.intellij.util.concurrency.QueueProcessor$RunnableConsumer.consume(QueueProcessor.java:277)
at com.intellij.util.concurrency.QueueProcessor.lambda$null$0(QueueProcessor.java:79)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:232)
at com.intellij.util.concurrency.QueueProcessor.lambda$wrappingProcessor$1(QueueProcessor.java:79)
at com.intellij.util.concurrency.QueueProcessor.lambda$null$3(QueueProcessor.java:212)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:232)
at com.intellij.util.concurrency.QueueProcessor.lambda$startProcessing$4(QueueProcessor.java:212)
at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
java.lang.NullPointerException
at com.android.tools.idea.run.GradleApplicationIdProvider.getTestPackageName(GradleApplicationIdProvider.java:122)
at com.android.tools.idea.run.AndroidLaunchTasksProvider.getConnectDebuggerTask(AndroidLaunchTasksProvider.java:225)
at com.android.tools.idea.run.LaunchTaskRunner.run(LaunchTaskRunner.java:85)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:736)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:580)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:525)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:85)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
at com.intellij.openapi.progress.impl.CoreProgressManager$4.run(CoreProgressManager.java:395)
at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
af...@gmail.com <af...@gmail.com> #10
Hi
I rechecked after comment#9 and noticed that you are right about android P. it was my mistake and I thought after one `-Xcompiler-option` I can add multiple compiler options, but now I noticed for each compiler option I need to use `-Xcompiler-option` one time.
I'm not sure what '--generate-mini-debug-info' does and if it is good to add to command line or not, but if it is good, we can add it android 8.1 (ani level 27) with this script too. I checked and it works for android api level 27 too. so Here is updated script:
wrapFile.withWriter { writer ->
writer.write('#!/system/bin/sh\n')
writer.write('processname=\$1\n')
writer.write('sdkversion=\$(getprop ro.build.version.sdk)\n')
writer.write('if [ "\$sdkversion" -gt "28" ]; then\n')
writer.write('fullpath="\$@"\n')
writer.write('elif [ "\$sdkversion" -eq "28" ]; then\n')
writer.write('shift\n')
writer.write('fullpath="\$processname -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable \$@"\n')
writer.write('elif [ "\$sdkversion" -eq "27" ]; then\n')
writer.write('shift\n')
writer.write('fullpath="\$processname -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable -Xcompiler-option --generate-mini-debug-info \$@"\n')
writer.write('else\n')
writer.write('log -p e -t "WRAPPER" "Wrapper script only works starting API level 27!"\n')
writer.write('exit 1\n')
writer.write('fi\n')
writer.write('\$fullpath\n')
}
In case of android Q, I cannot test, there is no emulator yet for android Q in android studio. But science comment#7 said "we fixed it for android Q", I used command line without any changes. But it seems you have some problems with it.
I rechecked after
I'm not sure what '--generate-mini-debug-info' does and if it is good to add to command line or not, but if it is good, we can add it android 8.1 (ani level 27) with this script too. I checked and it works for android api level 27 too. so Here is updated script:
wrapFile.withWriter { writer ->
writer.write('#!/system/bin/sh\n')
writer.write('processname=\$1\n')
writer.write('sdkversion=\$(getprop ro.build.version.sdk)\n')
writer.write('if [ "\$sdkversion" -gt "28" ]; then\n')
writer.write('fullpath="\$@"\n')
writer.write('elif [ "\$sdkversion" -eq "28" ]; then\n')
writer.write('shift\n')
writer.write('fullpath="\$processname -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable \$@"\n')
writer.write('elif [ "\$sdkversion" -eq "27" ]; then\n')
writer.write('shift\n')
writer.write('fullpath="\$processname -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable -Xcompiler-option --generate-mini-debug-info \$@"\n')
writer.write('else\n')
writer.write('log -p e -t "WRAPPER" "Wrapper script only works starting API level 27!"\n')
writer.write('exit 1\n')
writer.write('fi\n')
writer.write('\$fullpath\n')
}
In case of android Q, I cannot test, there is no emulator yet for android Q in android studio. But science
al...@google.com <al...@google.com> #11
For Q you need:
` writer.write('fullpath="\$processname -XjdwpProvider:adbconnection \$@"\n')`
` writer.write('fullpath="\$processname -XjdwpProvider:adbconnection \$@"\n')`
en...@google.com <en...@google.com> #12
we've updated the NDK wrap.sh documentation with the workaround.
Description
As you know, apks can provide a wrapper script starting android 8.1 for debugging purposes. This script is defined here:
But the problem is with providing this script, we will not we able to debug apk anymore even though wrap script runs app correctly. Since this problem and limitation is completely related to android itself (not related to NDK/SDK/Android studio), I report this bug here.
Steps to reproduce:
Add following wrap.sh (simplest possible) to any debuggable apk with target api 27+:
#!/system/bin/sh
"$@"
In this case, app starts, but we cannot debug app. But obviously, we should be able to debug app since wrap.sh is a feature for debugging purpose. I have tested this problem on both android 8.1 and 9 emulator and a real device running android 8.1.
I have gone though android source for days and I think I have found possible reason that this problem happens. I have described in problem and possible reason in here:
I will be happy to see any workaround for current time at least.
I have attacked a simple app and bug report from emulator after starting app is debug mode. As you see app says that Build is debug but debugger is not attached while it should.
Best Regards
Afshin