I\'m trying to put the equivalent of asm{int 3}
(or similar) into my iPhone program. My goal is to have Xcode stop exactly on the offending line, without having
int resume = false;
for (int i = 0; i < 20 && !resume; ++i)
sleep(1);
Above is a poor man's trap in that you have to manually attach to the program in question. Increase the delay as appropriate. Put the code where you want to break, and insert a breakpoint on the sleep statement, build and run your program, and attach to it from Xcode. Once Xcode breaks, you can right-click on the resume variable and edit it to 1, to resume execution.
To force xcode to break, use
kill(getpid(), SIGSTOP)
You can then step out/up and use lldb per usual. When you're done, you can hit continue and it works just like a breakpoint set from the Xcode GUI.
Tested with Swift 5 and Xcode 11.3
int pthread_kill(pthread_t thread, int sig);
allows for continuation, and pauses on the current thread, via pthread_self()
.
Similar to other signal functions (e.g., kill()
, raise()
, etc.), however,pthread_kill()
is used to request that a signal be delivered to a particular thread.
Pthread_kill Manual
I tried to find implementation that behaves the same as __debugbreak() that comes with Microsoft compiler and breaks inside my code and not somewhere inside system libraries and allows me to continue execution. This implementation of __debugbreak() works exactly as I wanted:
#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)
Direct equivalent of x86 int3
/ int 3
in arm / arm64 is
#if TARGET_CPU_ARM | TARGET_CPU_ARM64 | TARGET_CPU_ARM64E
asm volatile("trap");
#endif
std::runtime_error::runtime_error("breakpoint")
together with an XCode exception breakpoint of type
Exception:C++ "named:std::runtime"
worked for me (using XCode 8.0).
It yields the same result as if I had set a breakpoint manually at the line where the
std::runtime_error::runtime_error
function is called, i.e. correct thread, correct call stack, and the possibility to resume.