Self-mutating C (x86_64)
There's one small bug in your code here:

memcpy(foo_addr, shellcode, sizeof(shellcode));


This copies the contents of shellcode, but being a string literal, shellcode includes a null terminator and sizeof(shellcode) is equal to 30, not 29. You should replace this line with:

memcpy(foo_addr, shellcode, sizeof(shellcode) - 1);