This is a Mac OS X / GDB counterpart to Spiking Thread pattern previously described for Windows platforms (Volume 1, page 305):
(gdb) info threads 4 0×00007fff85b542df in sqrt$fenv_access_off () 3 0×00007fff8616ee42 in __semwait_signal () 2 0×00007fff8616ee42 in __semwait_signal () * 1 0×00007fff8616ee42 in __semwait_signal ()
We notice a non-waiting thread and switch to it:
(gdb) thread 4 [Switching to thread 4 (core thread 3)] 0x00007fff85b542df in sqrt$fenv_access_off () (gdb) bt #0 0x00007fff85b542df in sqrt$fenv_access_off () #1 0×000000010cc85dc9 in thread_three (arg=0×7fff6c884ac0) #2 0×00007fff8fac68bf in _pthread_start () #3 0×00007fff8fac9b75 in thread_start ()
If we disassemble the return address for thread_three function called from SQRT call we see an infinite loop:
(gdb) disass 0x000000010cc85dc9 Dump of assembler code for function thread_three: 0x000000010cc85db0 <thread_three+0>: push %rbp 0×000000010cc85db1 <thread_three+1>: mov %rsp,%rbp 0×000000010cc85db4 <thread_three+4>: sub $0×10,%rsp 0×000000010cc85db8 <thread_three+8>: mov %rdi,-0×10(%rbp) 0×000000010cc85dbc <thread_three+12>: mov -0×10(%rbp),%ax 0×000000010cc85dc0 <thread_three+16>: movsd (%rax),%xmm0 0×000000010cc85dc4 <thread_three+20>: callq 0×10cc85eac <dyld_stub_sqrt> 0×000000010cc85dc9 <thread_three+25>: mov -0×10(%rbp),%rax 0×000000010cc85dcd <thread_three+29>: movsd %xmm0,(%rax) 0×000000010cc85dd1 <thread_three+33>: jmpq 0×10cc85dbc <thread_three+12> End of assembler dump.
Here's the source code of the modeling application:
void * thread_one (void *arg) { while (1) { sleep (1); } return 0; }
void * thread_two (void *arg) { while (1) { sleep (2); } return 0; }
void * thread_three (void *arg) { while (1) { *(double*)arg=sqrt(*(double *)arg); } return 0; }
int main(int argc, const char * argv[]) { pthread_t threadID_one, threadID_two, threadID_three; double result = 0xffffffff; pthread_create (&threadID_one, NULL, thread_one, NULL); pthread_create (&threadID_two, NULL, thread_two, NULL); pthread_create (&threadID_three, NULL, thread_three, &result); pthread_join(threadID_three, NULL); return 0; }