I have this attempt to switch to a different stack by setting %rbp and %rsp:
#include <stdlib.h>
#include <stdio.h>
void* main_rbp = NULL;
void* main_rsp = NULL;
int run_stack() {
    int one = 1;
    printf("Hello from my new stack!\n");  // optimized to puts
    printf("crashes here but not when run with gdb\n"); // optimized to puts
    printf("1 = %d\n", one);
    return 0;
}
int main() {
    void* memory_block = malloc(1025);
    void* new_stack = memory_block + 1024;  // stack grows backwards, so start from end
    // save real stack pointers
    __asm__("movq %rbp, main_rbp(%rip)\n\t"
            "movq %rsp, main_rsp(%rip)\n\t");
    // set stack pointers to new_stack
    __asm__("movq -8(%rbp), %rsp\n\t"
            "movq -8(%rbp), %rbp\n\t");
    run_stack();
    // restore real stack pointers
    __asm__("movq main_rbp(%rip), %rbp\n\t"
            "movq main_rsp(%rip), %rsp\n\t");
    free(memory_block);
    printf("Still alive!\n");
    return 0;
}
And it segfaults:
$ ./main
Hello from my new stack!
crashes here but not when run with gdb
segmentation fault (core dumped) (or what it is in english)
But when I step through the same executable in gdb with pwndbg, everything (code flow, stack, registers) looks exactly as expected.
How can I track this issue down?
gdb output:
pwndbg> run
Starting program: ...../main 
Hello from my new stack!
crashes here but not when run with gdb
main_rbp: 0x7fffffffde20
main_rsp: 0x7fffffffde10
1 = 1
Still alive!
[Inferior 1 (process 22609) exited normally]
