summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/idevicedebug.c390
1 files changed, 200 insertions, 190 deletions
diff --git a/tools/idevicedebug.c b/tools/idevicedebug.c
index 53e84b7..b0c439d 100644
--- a/tools/idevicedebug.c
+++ b/tools/idevicedebug.c
@@ -338,226 +338,236 @@ int main(int argc, char *argv[])
338 goto cleanup; 338 goto cleanup;
339 } 339 }
340 340
341 switch (cmd) { 341 /* get the path to the app and it's working directory */
342 case CMD_RUN: 342 if (instproxy_client_start_service(device, &instproxy_client, TOOL_NAME) != INSTPROXY_E_SUCCESS) {
343 default: 343 fprintf(stderr, "Could not start installation proxy service.\n");
344 /* get the path to the app and it's working directory */ 344 goto cleanup;
345 if (instproxy_client_start_service(device, &instproxy_client, TOOL_NAME) != INSTPROXY_E_SUCCESS) { 345 }
346 fprintf(stderr, "Could not start installation proxy service.\n");
347 goto cleanup;
348 }
349 346
350 instproxy_client_get_path_for_bundle_identifier(instproxy_client, bundle_identifier, &path); 347 instproxy_client_get_path_for_bundle_identifier(instproxy_client, bundle_identifier, &path);
351 if (!path) { 348 if (!path) {
352 fprintf(stderr, "Invalid bundle identifier: %s\n", bundle_identifier); 349 fprintf(stderr, "Invalid bundle identifier: %s\n", bundle_identifier);
353 goto cleanup; 350 goto cleanup;
354 } 351 }
355 352
356 plist_t container = NULL; 353 plist_t container = NULL;
357 instproxy_client_get_object_by_key_from_info_dictionary_for_bundle_identifier(instproxy_client, bundle_identifier, "Container", &container); 354 instproxy_client_get_object_by_key_from_info_dictionary_for_bundle_identifier(instproxy_client, bundle_identifier, "Container", &container);
358 instproxy_client_free(instproxy_client); 355 instproxy_client_free(instproxy_client);
359 instproxy_client = NULL; 356 instproxy_client = NULL;
360
361 if (container && (plist_get_node_type(container) == PLIST_STRING)) {
362 plist_get_string_val(container, &working_directory);
363 log_debug("working_directory: %s\n", working_directory);
364 plist_free(container);
365 } else {
366 plist_free(container);
367 fprintf(stderr, "Could not determine container path for bundle identifier %s.\n", bundle_identifier);
368 goto cleanup;
369 }
370 357
371 /* start and connect to debugserver */ 358 if (container && (plist_get_node_type(container) == PLIST_STRING)) {
372 if (debugserver_client_start_service(device, &debugserver_client, TOOL_NAME) != DEBUGSERVER_E_SUCCESS) { 359 plist_get_string_val(container, &working_directory);
373 fprintf(stderr, 360 log_debug("working_directory: %s\n", working_directory);
374 "Could not start com.apple.debugserver!\n" 361 plist_free(container);
375 "Please make sure to mount the developer disk image first:\n" 362 } else {
376 " 1) Get the iOS version from `ideviceinfo -k ProductVersion`.\n" 363 plist_free(container);
377 " 2) Find the matching iPhoneOS DeveloperDiskImage.dmg files.\n" 364 fprintf(stderr, "Could not determine container path for bundle identifier %s.\n", bundle_identifier);
378 " 3) Run `ideviceimagemounter` with the above path.\n"); 365 goto cleanup;
379 goto cleanup; 366 }
380 }
381 367
382 /* set receive params */ 368 /* start and connect to debugserver */
383 if (debugserver_client_set_receive_params(debugserver_client, cancel_receive, 250) != DEBUGSERVER_E_SUCCESS) { 369 if (debugserver_client_start_service(device, &debugserver_client, TOOL_NAME) != DEBUGSERVER_E_SUCCESS) {
384 fprintf(stderr, "Error in debugserver_client_set_receive_params\n"); 370 fprintf(stderr,
385 goto cleanup; 371 "Could not start com.apple.debugserver!\n"
386 } 372 "Please make sure to mount the developer disk image first:\n"
373 " 1) Get the iOS version from `ideviceinfo -k ProductVersion`.\n"
374 " 2) Find the matching iPhoneOS DeveloperDiskImage.dmg files.\n"
375 " 3) Run `ideviceimagemounter` with the above path.\n");
376 goto cleanup;
377 }
387 378
388 /* enable logging for the session in debug mode */ 379 /* set receive params */
389 if (debug_level) { 380 if (debugserver_client_set_receive_params(debugserver_client, cancel_receive, 250) != DEBUGSERVER_E_SUCCESS) {
390 log_debug("Setting logging bitmask..."); 381 fprintf(stderr, "Error in debugserver_client_set_receive_params\n");
391 debugserver_command_new("QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE|LOG_RNB_PACKETS;", 0, NULL, &command); 382 goto cleanup;
392 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL); 383 }
393 debugserver_command_free(command);
394 command = NULL;
395 if (response) {
396 if (strncmp(response, "OK", 2)) {
397 debugserver_client_handle_response(debugserver_client, &response, NULL);
398 goto cleanup;
399 }
400 free(response);
401 response = NULL;
402 }
403 }
404 384
405 /* set maximum packet size */ 385 /* enable logging for the session in debug mode */
406 log_debug("Setting maximum packet size..."); 386 if (debug_level) {
407 char* packet_size[2] = {strdup("1024"), NULL}; 387 log_debug("Setting logging bitmask...");
408 debugserver_command_new("QSetMaxPacketSize:", 1, packet_size, &command); 388 debugserver_command_new("QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE|LOG_RNB_PACKETS;", 0, NULL, &command);
409 free(packet_size[0]); 389 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
410 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL); 390 debugserver_command_free(command);
411 debugserver_command_free(command); 391 command = NULL;
412 command = NULL; 392 if (response) {
413 if (response) { 393 if (strncmp(response, "OK", 2)) {
414 if (strncmp(response, "OK", 2)) { 394 debugserver_client_handle_response(debugserver_client, &response, NULL);
415 debugserver_client_handle_response(debugserver_client, &response, NULL); 395 goto cleanup;
416 goto cleanup;
417 }
418 free(response);
419 response = NULL;
420 } 396 }
397 free(response);
398 response = NULL;
399 }
400 }
421 401
422 /* set working directory */ 402 /* set maximum packet size */
423 log_debug("Setting working directory..."); 403 log_debug("Setting maximum packet size...");
424 char* working_dir[2] = {working_directory, NULL}; 404 char* packet_size[2] = { (char*)"1024", NULL};
425 debugserver_command_new("QSetWorkingDir:", 1, working_dir, &command); 405 debugserver_command_new("QSetMaxPacketSize:", 1, packet_size, &command);
426 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL); 406 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
427 debugserver_command_free(command); 407 debugserver_command_free(command);
428 command = NULL; 408 command = NULL;
429 if (response) { 409 if (response) {
430 if (strncmp(response, "OK", 2)) { 410 if (strncmp(response, "OK", 2)) {
431 debugserver_client_handle_response(debugserver_client, &response, NULL); 411 debugserver_client_handle_response(debugserver_client, &response, NULL);
432 goto cleanup; 412 goto cleanup;
433 } 413 }
434 free(response); 414 free(response);
435 response = NULL; 415 response = NULL;
436 } 416 }
437 417
438 /* set environment */ 418 /* set working directory */
439 if (environment) { 419 log_debug("Setting working directory...");
440 log_debug("Setting environment..."); 420 char* working_dir[2] = {working_directory, NULL};
441 for (environment_index = 0; environment_index < environment_count; environment_index++) { 421 debugserver_command_new("QSetWorkingDir:", 1, working_dir, &command);
442 log_debug("setting environment variable: %s", environment[environment_index]); 422 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
443 debugserver_client_set_environment_hex_encoded(debugserver_client, environment[environment_index], NULL); 423 debugserver_command_free(command);
444 } 424 command = NULL;
445 } 425 if (response) {
426 if (strncmp(response, "OK", 2)) {
427 debugserver_client_handle_response(debugserver_client, &response, NULL);
428 goto cleanup;
429 }
430 free(response);
431 response = NULL;
432 }
446 433
447 /* set arguments and run app */ 434 /* set environment */
448 log_debug("Setting argv..."); 435 if (environment) {
449 i++; /* i is the offset of the bundle identifier, thus skip it */ 436 log_debug("Setting environment...");
450 int app_argc = (argc - i + 2); 437 for (environment_index = 0; environment_index < environment_count; environment_index++) {
451 char **app_argv = (char**)malloc(sizeof(char*) * app_argc); 438 log_debug("setting environment variable: %s", environment[environment_index]);
452 app_argv[0] = path; 439 debugserver_client_set_environment_hex_encoded(debugserver_client, environment[environment_index], NULL);
453 log_debug("app_argv[%d] = %s", 0, app_argv[0]); 440 }
454 app_argc = 1; 441 }
455 while (i < argc && argv && argv[i]) {
456 log_debug("app_argv[%d] = %s", app_argc, argv[i]);
457 app_argv[app_argc++] = argv[i];
458 i++;
459 }
460 app_argv[app_argc] = NULL;
461 debugserver_client_set_argv(debugserver_client, app_argc, app_argv, NULL);
462 free(app_argv);
463 442
464 /* check if launch succeeded */ 443 /* set arguments and run app */
465 log_debug("Checking if launch succeeded..."); 444 log_debug("Setting argv...");
466 debugserver_command_new("qLaunchSuccess", 0, NULL, &command); 445 i++; /* i is the offset of the bundle identifier, thus skip it */
446 int app_argc = (argc - i + 2);
447 char **app_argv = (char**)malloc(sizeof(char*) * app_argc);
448 app_argv[0] = path;
449 log_debug("app_argv[%d] = %s", 0, app_argv[0]);
450 app_argc = 1;
451 while (i < argc && argv && argv[i]) {
452 log_debug("app_argv[%d] = %s", app_argc, argv[i]);
453 app_argv[app_argc++] = argv[i];
454 i++;
455 }
456 app_argv[app_argc] = NULL;
457 debugserver_client_set_argv(debugserver_client, app_argc, app_argv, NULL);
458 free(app_argv);
459
460 /* check if launch succeeded */
461 log_debug("Checking if launch succeeded...");
462 debugserver_command_new("qLaunchSuccess", 0, NULL, &command);
463 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
464 debugserver_command_free(command);
465 command = NULL;
466 if (response) {
467 if (strncmp(response, "OK", 2)) {
468 debugserver_client_handle_response(debugserver_client, &response, NULL);
469 goto cleanup;
470 }
471 free(response);
472 response = NULL;
473 }
474
475 if (cmd == CMD_RUN) {
476 if (detach_after_start) {
477 log_debug("Detaching from app");
478 debugserver_command_new("D", 0, NULL, &command);
467 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL); 479 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
468 debugserver_command_free(command); 480 debugserver_command_free(command);
469 command = NULL; 481 command = NULL;
470 if (response) {
471 if (strncmp(response, "OK", 2)) {
472 debugserver_client_handle_response(debugserver_client, &response, NULL);
473 goto cleanup;
474 }
475 free(response);
476 response = NULL;
477 }
478 482
479 if (detach_after_start) { 483 res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1;
480 log_debug("Detaching from app"); 484 goto cleanup;
481 debugserver_command_new("D", 0, NULL, &command); 485 }
482 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL); 486
483 debugserver_command_free(command); 487 /* set thread */
484 command = NULL; 488 log_debug("Setting thread...");
489 debugserver_command_new("Hc0", 0, NULL, &command);
490 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
491 debugserver_command_free(command);
492 command = NULL;
493 if (response) {
494 if (strncmp(response, "OK", 2)) {
495 debugserver_client_handle_response(debugserver_client, &response, NULL);
496 goto cleanup;
497 }
498 free(response);
499 response = NULL;
500 }
485 501
486 res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1; 502 /* continue running process */
503 log_debug("Continue running process...");
504 debugserver_command_new("c", 0, NULL, &command);
505 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
506 debugserver_command_free(command);
507 command = NULL;
508 log_debug("Continue response: %s", response);
509
510 /* main loop which is parsing/handling packets during the run */
511 log_debug("Entering run loop...");
512 while (!quit_flag) {
513 if (dres != DEBUGSERVER_E_SUCCESS) {
514 log_debug("failed to receive response; error %d", dres);
487 break; 515 break;
488 } 516 }
489 517
490 /* set thread */
491 log_debug("Setting thread...");
492 debugserver_command_new("Hc0", 0, NULL, &command);
493 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
494 debugserver_command_free(command);
495 command = NULL;
496 if (response) { 518 if (response) {
519 log_debug("response: %s", response);
497 if (strncmp(response, "OK", 2)) { 520 if (strncmp(response, "OK", 2)) {
498 debugserver_client_handle_response(debugserver_client, &response, NULL); 521 dres = debugserver_client_handle_response(debugserver_client, &response, &res);
499 goto cleanup; 522 if (dres != DEBUGSERVER_E_SUCCESS) {
500 } 523 log_debug("failed to process response; error %d; %s", dres, response);
501 free(response); 524 break;
502 response = NULL;
503 }
504
505 /* continue running process */
506 log_debug("Continue running process...");
507 debugserver_command_new("c", 0, NULL, &command);
508 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
509 debugserver_command_free(command);
510 command = NULL;
511
512 /* main loop which is parsing/handling packets during the run */
513 log_debug("Entering run loop...");
514 while (!quit_flag) {
515 if (dres != DEBUGSERVER_E_SUCCESS) {
516 log_debug("failed to receive response; error %d", dres);
517 break;
518 }
519
520 if (response) {
521 log_debug("response: %s", response);
522 if (strncmp(response, "OK", 2)) {
523 dres = debugserver_client_handle_response(debugserver_client, &response, &res);
524 if (dres != DEBUGSERVER_E_SUCCESS) {
525 log_debug("failed to process response; error %d; %s", dres, response);
526 break;
527 }
528 } 525 }
529 } 526 }
530 if (res >= 0) {
531 goto cleanup;
532 }
533
534 dres = debugserver_client_receive_response(debugserver_client, &response, NULL);
535 } 527 }
536 /* ignore quit_flag after this point */ 528 if (res >= 0) {
537 if (debugserver_client_set_receive_params(debugserver_client, NULL, 5000) != DEBUGSERVER_E_SUCCESS) {
538 fprintf(stderr, "Error in debugserver_client_set_receive_params\n");
539 goto cleanup; 529 goto cleanup;
540 } 530 }
541 531
542 /* kill process after we finished */ 532 dres = debugserver_client_receive_response(debugserver_client, &response, NULL);
543 log_debug("Killing process..."); 533 }
544 debugserver_command_new("k", 0, NULL, &command); 534
545 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL); 535 /* ignore quit_flag after this point */
546 debugserver_command_free(command); 536 if (debugserver_client_set_receive_params(debugserver_client, NULL, 5000) != DEBUGSERVER_E_SUCCESS) {
547 command = NULL; 537 fprintf(stderr, "Error in debugserver_client_set_receive_params\n");
548 if (response) { 538 goto cleanup;
549 if (strncmp(response, "OK", 2)) { 539 }
550 debugserver_client_handle_response(debugserver_client, &response, NULL); 540
551 goto cleanup; 541 /* interrupt execution */
552 } 542 debugserver_command_new("\x03", 0, NULL, &command);
553 free(response); 543 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
554 response = NULL; 544 debugserver_command_free(command);
545 command = NULL;
546 if (response) {
547 if (strncmp(response, "OK", 2)) {
548 debugserver_client_handle_response(debugserver_client, &response, NULL);
555 } 549 }
550 free(response);
551 response = NULL;
552 }
556 553
557 if (res < 0) { 554 /* kill process after we finished */
558 res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1; 555 log_debug("Killing process...");
556 debugserver_command_new("k", 0, NULL, &command);
557 dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
558 debugserver_command_free(command);
559 command = NULL;
560 if (response) {
561 if (strncmp(response, "OK", 2)) {
562 debugserver_client_handle_response(debugserver_client, &response, NULL);
559 } 563 }
560 break; 564 free(response);
565 response = NULL;
566 }
567
568 if (res < 0) {
569 res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1;
570 }
561 } 571 }
562 572
563cleanup: 573cleanup: