diff options
-rw-r--r-- | include/libimobiledevice/debugserver.h | 11 | ||||
-rw-r--r-- | src/debugserver.c | 13 | ||||
-rw-r--r-- | tools/idevicedebug.c | 50 |
3 files changed, 43 insertions, 31 deletions
diff --git a/include/libimobiledevice/debugserver.h b/include/libimobiledevice/debugserver.h index 03f97a4..90ba514 100644 --- a/include/libimobiledevice/debugserver.h +++ b/include/libimobiledevice/debugserver.h | |||
@@ -181,11 +181,16 @@ debugserver_error_t debugserver_client_set_ack_mode(debugserver_client_t client, | |||
181 | /** | 181 | /** |
182 | * Sets behavior when awaiting a response from the server. | 182 | * Sets behavior when awaiting a response from the server. |
183 | * | 183 | * |
184 | * @see debugserver_client_send_command, debugserver_client_receive_response, debugserver_client_receive | 184 | * @see debugserver_client_send_command, debugserver_client_receive_response, |
185 | * debugserver_client_receive | ||
185 | * | 186 | * |
186 | * @param client The debugserver client | 187 | * @param client The debugserver client |
187 | * @param cancel_receive A function pointer that will be called approximately every receive_loop_timeout milliseconds; the function should return a boolean flag specifying whether to stop waiting for a response. If NULL, behaves as if it always returns true. | 188 | * @param cancel_receive A function pointer that will be called approximately |
188 | * @param receive_loop_timeout Time in milliseconds between calls to cancel_receive. | 189 | * every receive_loop_timeout milliseconds; the function should return a |
190 | * boolean flag specifying whether to stop waiting for a response. If NULL, | ||
191 | * behaves as if it always returns true. | ||
192 | * @param receive_loop_timeout Time in milliseconds between calls to | ||
193 | * cancel_receive. | ||
189 | * | 194 | * |
190 | * @return DEBUGSERVER_E_SUCCESS on success, or an DEBUGSERVER_E_* error | 195 | * @return DEBUGSERVER_E_SUCCESS on success, or an DEBUGSERVER_E_* error |
191 | * code otherwise. | 196 | * code otherwise. |
diff --git a/src/debugserver.c b/src/debugserver.c index 4d653cf..1c20c25 100644 --- a/src/debugserver.c +++ b/src/debugserver.c | |||
@@ -89,8 +89,8 @@ LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_new(idevice_t device | |||
89 | debugserver_client_t client_loc = (debugserver_client_t) malloc(sizeof(struct debugserver_client_private)); | 89 | debugserver_client_t client_loc = (debugserver_client_t) malloc(sizeof(struct debugserver_client_private)); |
90 | client_loc->parent = parent; | 90 | client_loc->parent = parent; |
91 | client_loc->noack_mode = 0; | 91 | client_loc->noack_mode = 0; |
92 | client_loc->cancel_receive = NULL; | 92 | client_loc->cancel_receive = NULL; |
93 | client_loc->receive_loop_timeout = 1000; | 93 | client_loc->receive_loop_timeout = 1000; |
94 | 94 | ||
95 | *client = client_loc; | 95 | *client = client_loc; |
96 | 96 | ||
@@ -165,10 +165,11 @@ LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_with_timeout | |||
165 | LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive(debugserver_client_t client, char* data, uint32_t size, uint32_t *received) | 165 | LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive(debugserver_client_t client, char* data, uint32_t size, uint32_t *received) |
166 | { | 166 | { |
167 | debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR; | 167 | debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR; |
168 | do { | 168 | do { |
169 | res = debugserver_client_receive_with_timeout(client, data, size, received, client->receive_loop_timeout); | 169 | /* Is this allowed to return DEBUGSERVER_E_TIMEOUT and also set data and received? */ |
170 | } while (res == DEBUGSERVER_E_TIMEOUT && client->cancel_receive != NULL && !client->cancel_receive()); | 170 | res = debugserver_client_receive_with_timeout(client, data, size, received, client->receive_loop_timeout); |
171 | return res; | 171 | } while (res == DEBUGSERVER_E_TIMEOUT && client->cancel_receive != NULL && !client->cancel_receive()); |
172 | return res; | ||
172 | } | 173 | } |
173 | 174 | ||
174 | LIBIMOBILEDEVICE_API debugserver_error_t debugserver_command_new(const char* name, int argc, char* argv[], debugserver_command_t* command) | 175 | LIBIMOBILEDEVICE_API debugserver_error_t debugserver_command_new(const char* name, int argc, char* argv[], debugserver_command_t* command) |
diff --git a/tools/idevicedebug.c b/tools/idevicedebug.c index ae6dd02..67ef938 100644 --- a/tools/idevicedebug.c +++ b/tools/idevicedebug.c | |||
@@ -119,8 +119,9 @@ static debugserver_error_t debugserver_client_handle_response(debugserver_client | |||
119 | char* o = NULL; | 119 | char* o = NULL; |
120 | char* r = *response; | 120 | char* r = *response; |
121 | 121 | ||
122 | /* Documentation of response codes can be found here: | 122 | /* Documentation of response codes can be found here: |
123 | https://github.com/llvm/llvm-project/blob/4fe839ef3a51e0ea2e72ea2f8e209790489407a2/lldb/docs/lldb-gdb-remote.txt#L1269 */ | 123 | https://github.com/llvm/llvm-project/blob/4fe839ef3a51e0ea2e72ea2f8e209790489407a2/lldb/docs/lldb-gdb-remote.txt#L1269 |
124 | */ | ||
124 | 125 | ||
125 | if (r[0] == 'O') { | 126 | if (r[0] == 'O') { |
126 | /* stdout/stderr */ | 127 | /* stdout/stderr */ |
@@ -130,8 +131,11 @@ static debugserver_error_t debugserver_client_handle_response(debugserver_client | |||
130 | } else if (r[0] == 'T') { | 131 | } else if (r[0] == 'T') { |
131 | /* thread stopped information */ | 132 | /* thread stopped information */ |
132 | log_debug("Thread stopped. Details:\n%s", r + 1); | 133 | log_debug("Thread stopped. Details:\n%s", r + 1); |
133 | if (exit_status != NULL) { | 134 | if (exit_status != NULL) { |
134 | /* "Thread stopped" seems to happen when assert() fails. Use bash convention where signals cause an exit status of 128 + signal */ | 135 | /* "Thread stopped" seems to happen when assert() fails. |
136 | Use bash convention where signals cause an exit | ||
137 | status of 128 + signal | ||
138 | */ | ||
135 | *exit_status = 128 + SIGABRT; | 139 | *exit_status = 128 + SIGABRT; |
136 | } | 140 | } |
137 | /* Break out of the loop. */ | 141 | /* Break out of the loop. */ |
@@ -143,13 +147,15 @@ static debugserver_error_t debugserver_client_handle_response(debugserver_client | |||
143 | debugserver_decode_string(r + 1, strlen(r) - 1, &o); | 147 | debugserver_decode_string(r + 1, strlen(r) - 1, &o); |
144 | if (o != NULL) { | 148 | if (o != NULL) { |
145 | printf("Exit %s: %u\n", (r[0] == 'W' ? "status" : "due to signal"), o[0]); | 149 | printf("Exit %s: %u\n", (r[0] == 'W' ? "status" : "due to signal"), o[0]); |
146 | if (exit_status != NULL) { | 150 | if (exit_status != NULL) { |
147 | /* Use bash convention where signals cause an exit status of 128 + signal */ | 151 | /* Use bash convention where signals cause an |
148 | *exit_status = o[0] + (r[0] == 'W' ? 0 : 128); | 152 | exit status of 128 + signal |
149 | } | 153 | */ |
154 | *exit_status = o[0] + (r[0] == 'W' ? 0 : 128); | ||
155 | } | ||
150 | } else { | 156 | } else { |
151 | debug_info("Unable to decode exit status from %s", r); | 157 | debug_info("Unable to decode exit status from %s", r); |
152 | dres = DEBUGSERVER_E_UNKNOWN_ERROR; | 158 | dres = DEBUGSERVER_E_UNKNOWN_ERROR; |
153 | } | 159 | } |
154 | } else if (r && strlen(r) == 0) { | 160 | } else if (r && strlen(r) == 0) { |
155 | log_debug("empty response"); | 161 | log_debug("empty response"); |
@@ -157,13 +163,13 @@ static debugserver_error_t debugserver_client_handle_response(debugserver_client | |||
157 | log_debug("ERROR: unhandled response '%s'", r); | 163 | log_debug("ERROR: unhandled response '%s'", r); |
158 | } | 164 | } |
159 | 165 | ||
160 | if (o != NULL) { | 166 | if (o != NULL) { |
161 | free(o); | 167 | free(o); |
162 | o = NULL; | 168 | o = NULL; |
163 | } | 169 | } |
164 | 170 | ||
165 | free(*response); | 171 | free(*response); |
166 | *response = NULL; | 172 | *response = NULL; |
167 | return dres; | 173 | return dres; |
168 | } | 174 | } |
169 | 175 | ||
@@ -351,8 +357,8 @@ int main(int argc, char *argv[]) | |||
351 | goto cleanup; | 357 | goto cleanup; |
352 | } | 358 | } |
353 | 359 | ||
354 | /* set receive params */ | 360 | /* set receive params */ |
355 | if (debugserver_client_set_receive_params(debugserver_client, cancel_receive, 250) != DEBUGSERVER_E_SUCCESS) { | 361 | if (debugserver_client_set_receive_params(debugserver_client, cancel_receive, 250) != DEBUGSERVER_E_SUCCESS) { |
356 | fprintf(stderr, "Error in debugserver_client_set_receive_params\n"); | 362 | fprintf(stderr, "Error in debugserver_client_set_receive_params\n"); |
357 | goto cleanup; | 363 | goto cleanup; |
358 | } | 364 | } |
@@ -494,7 +500,7 @@ int main(int argc, char *argv[]) | |||
494 | if (strncmp(response, "OK", 2)) { | 500 | if (strncmp(response, "OK", 2)) { |
495 | dres = debugserver_client_handle_response(debugserver_client, &response, &res); | 501 | dres = debugserver_client_handle_response(debugserver_client, &response, &res); |
496 | if (dres != DEBUGSERVER_E_SUCCESS) { | 502 | if (dres != DEBUGSERVER_E_SUCCESS) { |
497 | debug_info("failed to process response; error %d; %s", dres, response); | 503 | log_debug("failed to process response; error %d; %s", dres, response); |
498 | break; | 504 | break; |
499 | } | 505 | } |
500 | } | 506 | } |
@@ -521,9 +527,9 @@ int main(int argc, char *argv[]) | |||
521 | response = NULL; | 527 | response = NULL; |
522 | } | 528 | } |
523 | 529 | ||
524 | if (res < 0) { | 530 | if (res < 0) { |
525 | res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1; | 531 | res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1; |
526 | } | 532 | } |
527 | break; | 533 | break; |
528 | } | 534 | } |
529 | 535 | ||