Ответ 1
raise(SIGTRAP)
- относительно переносимый способ иметь контрольную точку "в коде".
Я пытаюсь помещать эквивалент 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.)
[Этот вопрос появился первоначально под другим названием. Я отредактировал его, надеюсь, сделать все более ясным.]
raise(SIGTRAP)
- относительно переносимый способ иметь контрольную точку "в коде".
Try:
__builtin_trap();
работает как на Mac, так и на iOS, и вы можете перетащить маленький зеленый курсор на следующую строку, чтобы продолжить работу.
Я пробовал все эти решения, и хотя @RichardGroves отвечает на сохранение стека, лучшим решением является:
Debug::assert(...)
Это потому, что это единственный надежный способ как для
Я тоже. Я поставил некоторый код, который делает то, что мы хотим +, объяснение того, что мы хотим в http://iphone.m20.nl/wp/2010/10/xcode-iphone-debugger-halt-assertions/ - это первое сообщение, t должны выглядеть слишком тяжело.
int resume = false;
for (int i = 0; i < 20 && !resume; ++i)
sleep(1);
Выше - ловушка для бедных людей, которую вы должны вручную привязать к рассматриваемой программе. Увеличьте задержку по мере необходимости. Поместите код, в который вы хотите сломать, и вставьте точку останова в оператор сна, создайте и запустите свою программу и привяжите ее к Xcode. Как только Xcode разрывается, вы можете щелкнуть правой кнопкой мыши по переменной resume и отредактировать ее до 1, чтобы возобновить выполнение.
Я попытался найти реализацию, которая ведет себя так же, как __ 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)
int pthread_kill(pthread_t thread, int sig);
позволяет продолжить и приостанавливать текущий поток через pthread_self()
.
Как и другие функции сигнала (например, kill()
, raise()
и т.д.), однако pthread_kill()
используется для запроса передачи сигнала в конкретный поток.
std::runtime_error::runtime_error("breakpoint")
вместе с контрольной точкой исключения XCode типа
Исключение: С++ "named: std:: runtime"
работал у меня (используя XCode 8.0).
Это дает тот же результат, как если бы я установил точку останова вручную в строке, где
std::runtime_error::runtime_error
Вызывается функция то есть правильная нить, правильный стек вызовов и возможность возобновления.