9

What is the significance of

android.os.Debug.waitForDebugger();

I am aware that we [sometimes] need to use this function in order to debug a Service, but my question is:

  • WHY do we have to do this?
  • Why does this method exist? What other purpose does it serve?
  • What does it mean to attach a debugger to a process, and why do we have to do this? Why does a Service have to be debugged in this way, and not an Activity or BroadcastReceiver?

One would think that debugging any kind of code in a project would be straightforward. Except it isn't. Not for a Service anyway.

What is the reason for the existence of this special procedure? And what else is it used for?

enter image description here

Wait until a debugger attaches. As soon as the debugger attaches, this returns, so you will need to place a breakpoint after the waitForDebugger() call if you want to start tracing immediately.

The WHY remains unanswered.

UPDATE:

I found one use case for this function: when an Android app is auto-restarted after the app process is killed. The process is killed when a runtime permission is toggled by the user in the app settings. More generally, an app process is killed & restarted whenever ...

android.os.Process.killProcess(android.os.Process.myPid());

is called.

To debug the app after process restart, you write android.os.Debug.waitForDebugger() in your code and then attach the debugger to the current process.

Android: how to debug app's start-up process.

This is one use case for this function.

References:

Debugging a service.

A proper way to Debug a Service in Android Studio?.

Breakpoint in service not working.

How to debug an Android Background Service?.

How to debug a Service?.

How to Attach debbuger to process from the first line without compile code every time.

you can attach a debugger after the app is already open.

Possibly related:

Accessibility service disabled upon each debug run

When using the Java debugger in Intellij what does “Drop Frame” mean?

Configure on-device developer options.

Test your service.

Force application to restart from first Activity.

Yash Sampat
  • 30,051
  • 12
  • 94
  • 120
  • 2
    The person who tried to close / downvote this question neither knows the answer nor is not capable of answering it. I posted this question because no one has asked it. – Yash Sampat Sep 24 '19 at 09:52
  • 1
    who said in the [official android documentation](https://developer.android.com/docs) that you need `android.os.Debug.waitForDebugger()` in order to debug `Service`'s code? – pskink Sep 24 '19 at 09:53
  • Well, breakpoints are only hit when you do this. It isn't mentioned in the official docs, but then a lot of things aren't ... :) – Yash Sampat Sep 24 '19 at 09:55
  • 1
    no, it is not true: service code is not handled in any other way than activity code – pskink Sep 24 '19 at 09:56
  • You should try it first. I know its strange. That's why I've asked the question. Others have also seen this. See the references. – Yash Sampat Sep 24 '19 at 09:59
  • 2
    the question is indeed interesting, however it is too broad. – Daniel Sep 24 '19 at 10:04
  • @Daniel: penny for your thoughts ... :) – Yash Sampat Sep 24 '19 at 10:15
  • 1
    yes, I first tried: I put a breakpoint in the first line of `onStartCommand` and called `startService` and the debugger stopped on that breakpoint - if you are using services that are running in the different process than original package then write it explicitly in your question - normal services work with no problems – pskink Sep 24 '19 at 10:32
  • I'm glad for you. This is a known issue with Services, however. I'm trying to understand why this is done, and what it means to attach a debugger to a process and WHY. – Yash Sampat Sep 24 '19 at 10:34
  • does your service have `android:process=..` attribute in the `AndroidManifest.xml` file? – pskink Sep 24 '19 at 11:28
  • @pskink: No but it has exported=true. – Yash Sampat Sep 24 '19 at 11:57
  • So your service runs in the same procces your whole package runs - just setup a breakpoint and debug service code like you debug any activity code – pskink Sep 24 '19 at 12:04
  • @pskink: yes, it should. Except it doesn't. – Yash Sampat Sep 24 '19 at 12:26

1 Answers1

6

I don't sure my answer would be right, because you might expect complicated insights inside. In reality, there is pretty straight forward process, to connect and intercept process responses.

enter image description here

  • Why does this method exist? What other purpose does it serve?

As you can see, answering this question is pretty simple. Because of race condition during process interception, you will not be able to stop on your early break point, and should call waitForDebugger(). In most frequent places, like Service debugging and Application.

  • What does it mean to "attach a debugger to a process", and why do we have to do this? Why does a Service have to be debugged in this way, and not an Activity or BroadcastReceiver?

It's another question and I don't sure about context here, but. We need to call the method, and attach to process manually for cases, where our Service using another process from a Manifest. Obviously debug bridge will set on the current active process with application, but since we can run Service from another process, we need to manually add it to debug bridge and wait for debug connection.

GensaGames
  • 5,538
  • 4
  • 24
  • 53
  • Very interesting. This is just what I want, with more detail and examples. Is a `Service` always run in the same process as the App, by default? – Yash Sampat Oct 10 '19 at 10:24
  • 1
    @Y.S Sorry, was busy because of workplace change) `Service` always running at the same process as application. Unless you change it in manifest, *Why there is ability to make `Service` work from another process?* For cases, where you application and background SHOULD work separately. Just for ex. `Player`. By closing player application you are destroying process of it, but you need to keep music playing. To keep alive tasks with active music, you could have `Service` with separate process. – GensaGames Oct 16 '19 at 16:19
  • 1
    @Y.S Another very tricky example of using `Service` with separate process, it's because of handling native crashes. By default, you CANNOT catch exceptions in native libraries. Instead, you can place native levers in the `Service` with another process and create `Binder` for communication. In case of crash, you background Service will go down, but main application continue working. And can restart Service again. – GensaGames Oct 16 '19 at 16:22