Подтвердить что ты не робот

Могу ли я создать точку останова в коде в iOS, например `__asm ​​{int 3}` на VС++, и продолжить выполнение после того, как она была удалена?

Я пытаюсь помещать эквивалент asm{int 3} (или аналогичный) в мою программу для iPhone. Моя цель состоит в том, чтобы Xcode останавливался точно на линии нарушения, не имея необходимости возиться со стеком вызовов (так что _Debugger не звучит так, как будто бы это делало, а не то, что я мог бы найти, какой фреймворк он в любом случае...) и оставить меня в состоянии возобновить выполнение (вот почему я не доволен assert).

(Я использую оба эти поведения в других системах, и я хотел бы воспроизвести их на iOS.)

Моя лучшая попытка до сих пор была такой:

asm volatile("bkpt 1");

Это останавливает Xcode в соответствующей строке, но когда я пытаюсь продолжить работу с Cmd + Alt + P, появляется Xcode, который снова запускает BKPT. И если я использую Shift + Cmd + O, я просто получаю следующее:

Watchdog has expired.  Remote device was disconnected?  Debugging session terminated.

(Разумеется, удаленное устройство все еще подключено.)

У меня нет большого опыта работы с iOS, Mac, ARM, gdb или gcc asm. Так что я уже в тупике. Есть ли способ заставить iOS и Xcode делать то, что я хочу?

(Я не знаю, имеет ли это значение, но, судя по размеру моей команды, это код ARM.)

[Этот вопрос появился первоначально под другим названием. Я отредактировал его, надеюсь, сделать все более ясным.]

4b9b3361

Ответ 1

raise(SIGTRAP) - относительно переносимый способ иметь контрольную точку "в коде".

Ответ 2

Try:

__builtin_trap();

работает как на Mac, так и на iOS, и вы можете перетащить маленький зеленый курсор на следующую строку, чтобы продолжить работу.

Ответ 3

Я пробовал все эти решения, и хотя @RichardGroves отвечает на сохранение стека, лучшим решением является:

  • создайте свой собственный метод assert, например Debug::assert(...)
  • установить точку останова в XCode для этой реализации
  • используйте команду "Выход", чтобы вернуться к вызывающему абоненту

Это потому, что это единственный надежный способ как для

  • просмотр трассировки стека
  • шаг/продолжение

Ответ 4

Я тоже. Я поставил некоторый код, который делает то, что мы хотим +, объяснение того, что мы хотим в http://iphone.m20.nl/wp/2010/10/xcode-iphone-debugger-halt-assertions/ - это первое сообщение, t должны выглядеть слишком тяжело.

Ответ 5

int resume = false;
for (int i = 0; i < 20 && !resume; ++i)
    sleep(1);

Выше - ловушка для бедных людей, которую вы должны вручную привязать к рассматриваемой программе. Увеличьте задержку по мере необходимости. Поместите код, в который вы хотите сломать, и вставьте точку останова в оператор сна, создайте и запустите свою программу и привяжите ее к Xcode. Как только Xcode разрывается, вы можете щелкнуть правой кнопкой мыши по переменной resume и отредактировать ее до 1, чтобы возобновить выполнение.

Снимок экрана

Ответ 6

Я попытался найти реализацию, которая ведет себя так же, как __ debugbreak(), которая поставляется с компилятором Microsoft и разбивается внутри моего кода, а не где-то внутри системных библиотек и позволяет продолжить выполнение. Эта реализация __debugbreak() работает точно так, как я хотел:

#if defined(__APPLE__) && defined(__aarch64__)
#define __debugbreak() __asm__ __volatile__(            \
    "   mov    x0, %x0;    \n" /* pid                */ \
    "   mov    x1, #0x11;  \n" /* SIGSTOP            */ \
    "   mov    x16, #0x25; \n" /* syscall 37 = kill  */ \
    "   svc    #0x80       \n" /* software interrupt */ \
    "   mov    x0, x0      \n" /* nop                */ \
    ::  "r"(getpid())                                   \
    :   "x0", "x1", "x16", "memory")
#elif defined(__APPLE__) && defined(__arm__)
#define __debugbreak() __asm__ __volatile__(            \
    "   mov    r0, %0;     \n" /* pid                */ \
    "   mov    r1, #0x11;  \n" /* SIGSTOP            */ \
    "   mov    r12, #0x25; \n" /* syscall 37 = kill  */ \
    "   svc    #0x80       \n" /* software interrupt */ \
    "   mov    r0, r0      \n" /* nop                */ \
    ::  "r"(getpid())                                   \
    :   "r0", "r1", "r12", "memory")
#elif defined(__APPLE__) && defined(__i386__)
#define __debugbreak() __asm__ __volatile__("int $3; mov %eax, %eax")
#endif

#define ASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)

Ответ 7

int pthread_kill(pthread_t thread, int sig); позволяет продолжить и приостанавливать текущий поток через pthread_self().

Как и другие функции сигнала (например, kill(), raise() и т.д.), однако pthread_kill() используется для запроса передачи сигнала в конкретный поток.

Руководство Pthread_kill

Ответ 8

std::runtime_error::runtime_error("breakpoint")

вместе с контрольной точкой исключения XCode типа

Исключение: С++ "named: std:: runtime"

работал у меня (используя XCode 8.0).
Это дает тот же результат, как если бы я установил точку останова вручную в строке, где

std::runtime_error::runtime_error
Вызывается функция

то есть правильная нить, правильный стек вызовов и возможность возобновления.