c++ - aserciones - assert python
Resumible assert/breakpoint en iOS como__debugbreak() con compilador de MS (1)
Estoy tratando de implementar macro de activos personalizados (similar a lo que assert.h tiene), pero quiero poder continuar la ejecución después de obtener y afirmar.
Por ejemplo, una implementación de ASSERT
tal podría ser:
#define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0)))
__debugbreak es una función intrínseca de los compiladores de Microsoft que inserta un punto de corte de software, equivalente a _asm int 3
en x86. para iOS hay diferentes formas de implementar ese __debugbreak:
-
__asm__("int $3");
para x86. -
__asm__("bkpt #0");
para el brazo normal. -
__asm__("brk #0");
para arm64 - __builtin_trap ()
-
raise(SIGTRAP)
pero con todos ellos cuando mi afirmación golpea, no puedo simplemente dar un paso más y continuar la forma en que puedo hacerlo cuando trabajo con Visual Studio; cuando algo afirma en mis compilaciones de iOS se queda atascado en la afirmación y no tengo más opción que terminar, ni siquiera puedo mover el puntero de instrucción manualmente y omitir la afirmación.
¿Es posible implementar afirmaciones en iOS que entrarían en el depurador y me permitirían continuar la ejecución?
Resulta que puedo lograr lo que quiero haciendo un syscall:
#include <unistd.h>
#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__) || defined(__x86_64__))
#define __debugbreak() __asm__ __volatile__("int $3; mov %eax, %eax")
#endif
#define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)
Hay un mov x0, x0
NOP posterior mov x0, x0
por una razón: cuando assert se rompe, el depurador se detendrá exactamente en la línea de afirmación y no en alguna línea aleatoria donde se encuentre la siguiente instrucción.
En caso de que alguien esté buscando el equivalente de IsDebuggerPresent en iOS, puede usar AmIBeingDebugged .