Respected community members, Hi, Please find attached a patch. {See: 0001-Fix-AIX-thr-NULL-assertion-failure-during-fork.patch} This patch is a fix to assertion switch_to_thread: Assertion `thr != NULL' in AIX. Reproducing this in AIX:- Consider the program pasted below this email named as multi-thread-fork.c. This program creates two threads and each thread forks. Only in the case where a user sets to follow the child after fork this assertion failure is seen. In remaining cases {detach_on_fork = on and follow parent, detach on fork = off and follow child and detach on fork off and follow parent} we can debug the code multi-thread-fork.c. For example, consider output 1 pasted below this email to see the failure. The root cause:- Assume we have set detach_on_fork = on and set follow-fork-mode child. In AIX, on a fork () event we set our status and return our parent ptid from rs6000-aix-nat.c.. Once the object file of the new_inferior or child process is loaded we call pd_enable () to set our thread target and sync our threadlists. In our sync_threadlists we have pbuf having our pthread library threads and gbuf having our GDB threads known to GDB core that have been registered. The condition if (gptid.is_pid ()) in the function sync_threadlists () will hit when the child process becomes threaded and the child process from ptid_t (pid, 0, 0) is changed to ptid_t (pid, 0, uthid). After this we return this ptid and the control is now onto GDB generic code where in the infrun.c code, a decision is made in the function follow_fork () in the case TARGET_WAITKIND_FORKED: at line number 897 that if we follow the child, we should switch to thread child of parent as shown below if (follow_child) +898 { +899 tp = parent_targ->find_thread (child); +900 switch_to_thread (tp); …….. Here the child is a ptid_t unfortunately with a ptid_t (pid, 0 ,0) instead of ptid_t (pid, 0, tid) which we changed in the sync_threadlists () of aix-thread.c.. So, when a switch to thread here happens ptid_t (pid, 0 ,0) GDB is surprised that this thread does not exist leading to assertion failure. The FIX:- While I cannot say with 100% surety that from where GDB core got this ptid and why it did not update to ptid_t (pid, 0, tid) , my observation post debugging is that GDB core would have got ptid_t(pid, 0, 0) from the rs6000-aix-nat.c file, inside the wait () where we did inform GDB by setting a status that this a child process belonging a parent process on a fork event. GDB could not change this ptid it got during the fork event, even though we changed it later via sync_threadlists () from aix-thread.c for the threaded event. Having said that, since in rs6000-aix-nat.c we do not handle any thread related debug behaviour, in our aix-thread.c file I have added a condition such that if there is only one thread that belongs to a process then that process is not multithreaded and need to have thread ptid changed. This fixed the issue as show below this email in Output 2. Kindly let me know what you think. Have a nice day ahead. Thanks and regards, Aditya. Multi-thread-fork.c # cat ~/gdb_tests/multi-thread-fork.c #include #include #include #include #include pthread_barrier_t barrier; #define NUM_THREADS 2 void * thread_function (void *arg) { /* This ensures that the breakpoint is only hit after both threads are created, so the test can always switch to the non-event thread when the breakpoint triggers. */ pthread_barrier_wait (&barrier); pid_t p; p = fork(); if(p<0) { perror("fork fail"); exit(1); } // child process because return value zero else if ( p == 0) printf("Hello from Child!\n"); // parent process because return value non-zero. else printf("Hello from Parent!\n"); while (1); /* break here */ } int main (void) { int i; alarm (300); pthread_barrier_init (&barrier, NULL, NUM_THREADS); for (i = 0; i < NUM_THREADS; i++) { pthread_t thread; int res; res = pthread_create (&thread, NULL, thread_function, NULL); assert (res == 0); } while (1) sleep (1); return 0; } Output 1:- ./gdb ~/gdb_tests/multi-thread-fork GNU gdb (GDB) 15.0.50.20231117-git Copyright (C) 2023 Free Software Foundation, Inc.--- Reading symbols from //gdb_tests/multi-thread-fork... (gdb) set follow-fork-mode child (gdb) r Starting program: /gdb_tests/multi-thread-fork [New Thread 258] [New Thread 515] [Attaching after Thread 515 fork to child process 7602578] [New inferior 2 (process 7602578)] [Detaching after fork from parent process 6750654] Hello from Parent! [Inferior 1 (process 6750654) detached] Hello from Child! Hello from Parent! thread.c:1380: internal-error: switch_to_thread: Assertion `thr != NULL' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- 0x1008e05db ??? 0x1008e07a3 ??? 0x1000437f7 ???------- x100000aff ??? 0x100000583 ??? --------------------- thread.c:1380: internal-error: switch_to_thread: Assertion `thr != NULL' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) y Output 2:- Reading symbols from //gdb_tests/multi-thread-fork... (gdb) set follow-fork-mode child (gdb) r Starting program: /gdb_tests/multi-thread-fork [New Thread 258] [New Thread 515] [Attaching after Thread 515 fork to child process 11403720] [New inferior 2 (process 11403720)] [Detaching after fork from parent process 16515532] [Inferior 1 (process 16515532) detached] Hello from Parent! Hello from Child! Hello from Parent! Hello from Child! Thread 2.1 received signal SIGINT, Interrupt. [Switching to process 11403720] thread_function (arg=0x0) at //gdb_tests/multi-thread-fork.c:50 50 while (1); /* break here */ (gdb)