loadAndConnectViaJDWP connects to the application waiting for a JDWP connection with the specified process id, sends a number of JDWP commands to load the list of libraries.
( ctx context.Context, gapidAPK *gapidapk.APK, pid int, d adb.Device)
| 128 | // connection with the specified process id, sends a number of JDWP commands to |
| 129 | // load the list of libraries. |
| 130 | func (p *Process) loadAndConnectViaJDWP( |
| 131 | ctx context.Context, |
| 132 | gapidAPK *gapidapk.APK, |
| 133 | pid int, |
| 134 | d adb.Device) error { |
| 135 | |
| 136 | const ( |
| 137 | reconnectAttempts = 10 |
| 138 | reconnectDelay = time.Second |
| 139 | ) |
| 140 | |
| 141 | jdwpPort, err := adb.LocalFreeTCPPort() |
| 142 | if err != nil { |
| 143 | return log.Err(ctx, err, "Finding free port") |
| 144 | } |
| 145 | ctx = log.V{"jdwpPort": jdwpPort}.Bind(ctx) |
| 146 | |
| 147 | log.I(ctx, "Forwarding TCP port %v -> JDWP pid %v", jdwpPort, pid) |
| 148 | if err := d.Forward(ctx, adb.TCPPort(jdwpPort), adb.Jdwp(pid)); err != nil { |
| 149 | return log.Err(ctx, err, "Setting up JDWP port forwarding") |
| 150 | } |
| 151 | defer func() { |
| 152 | // Clone context to ignore cancellation. |
| 153 | ctx := keys.Clone(context.Background(), ctx) |
| 154 | d.RemoveForward(ctx, adb.TCPPort(jdwpPort)) |
| 155 | }() |
| 156 | |
| 157 | ctx, stop := task.WithCancel(ctx) |
| 158 | defer stop() |
| 159 | |
| 160 | log.I(ctx, "Connecting to JDWP") |
| 161 | |
| 162 | // Create a JDWP connection with the application. |
| 163 | var sock net.Conn |
| 164 | var conn *jdwp.Connection |
| 165 | err = task.Retry(ctx, reconnectAttempts, reconnectDelay, func(ctx context.Context) (bool, error) { |
| 166 | if sock, err = net.Dial("tcp", fmt.Sprintf("localhost:%v", jdwpPort)); err != nil { |
| 167 | return false, err |
| 168 | } |
| 169 | if conn, err = jdwp.Open(ctx, sock); err != nil { |
| 170 | sock.Close() |
| 171 | log.I(ctx, "Failed to connect to the application: %v. Retrying...", err) |
| 172 | return false, err |
| 173 | } |
| 174 | return true, nil |
| 175 | }) |
| 176 | if err != nil { |
| 177 | if err == io.EOF { |
| 178 | analytics.SendBug(911, analytics.TargetDevice(d.Instance().GetConfiguration())) |
| 179 | return fmt.Errorf("Unable to connect to the application.\n\n" + |
| 180 | "This can happen when another debugger or IDE is running " + |
| 181 | "in the background, such as Android Studio.\n" + |
| 182 | "Please close any running Android debuggers and try again.\n\n" + |
| 183 | "See https://github.com/google/gapid/issues/911 for more " + |
| 184 | "information") |
| 185 | } |
| 186 | return log.Err(ctx, err, "Connecting to JDWP") |
| 187 | } |
no test coverage detected