Re: Error record and replay target doesn't support syscall number 435
Guinevere Larsen via Gdb <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <[email protected]> |
Re-adding gdb list, since you mentioned you dropped on accident On 5/13/24 12:13, Navin P wrote: > On Mon, May 13, 2024 at 6:40 PM Guinevere Larsen <[email protected]> wrote: >> On 5/13/24 08:06, Navin P wrote: >>> Hi, >> Hi! :) >>> On Fri, May 10, 2024 at 7:29 PM Guinevere Larsen <[email protected]> wrote: >>>> On 5/10/24 05:07, Navin P via Gdb wrote: >>>>> Hi, >>>>> I tried to record a program calling C++ threads and then did a >>>>> break on main , then record and continue it throws the error message >>>>> "record and replay target doesn't support syscall number 435" . What >>>>> should I do to support syscall number 435 ? >>>> Hi! >>>> >>>> I can't answer everything, since I'm not too familiar with syscalls >>>> specifically, but I'll do my best! >>>> >>>> My first road bump with this is that we record that a clone has >>>> happened, but we can only record the process that GDB is following >>>> (parent or child, depending on follow-fork-mode). This is >>>> counter-intuitive to me, since I would have expected the full inferior >>>> to be replayed. >>> To get this working you need minimum changes of current_inferior to >>> for each inferior in all_inferiors() and execute that function for >>> each inferior. >>> return values have to be captured in a list. Similarly for each return value >>> you have to perform the actions in a loop. >> There is an extra complication, the recording subsystem was added before >> GDB could handle multiple inferiors, so it works on the assumption that >> you only need one global history. Meaning if we did record for all >> inferiors or all processes, the history would be mangled, jumping from >> one inferior to the next. It is already a problem in handling >> multi-threaded inferiors, so a proper fix would require having a >> per-thread history, and possibly some way to serialize the execution. >> >> I added the explanation more as a motivator to why I think we should >> warn the user of the counter-intuitive behavior, at least in the >> documentation. >> >>> It is going to definitely slow down execution by orders of magnitude. >> Absolutely! I'm almost wondering if we should try to spawn a recording >> thread per process or thread, to at least make multi-threaded recording >> not worse. But that is far in the future, unrelated to this change > static void > record_full_core_open_1 () > { > regcache *regcache = get_thread_regcache (inferior_thread ()) > > In record-full.c we have inferior_thread() which is the current thread, > so only 1 thread is recorded ? That is my observation too. I am not sure if only thread 1 is recorded, or if it is mixing instructions from all threads, but only changing register values for one of the threads. You can disassemble thread 1, then reverse-stepi to see if the PC changes wildly or if phantom instructions show up. > If so, what is required to fix it for all threads. I haven't fully accounted for everything that is required to make record work for multi-threaded inferiors. What I know we strictly need to either double-check or improve is: * If you check gdb/record-full.c:197, you'll see how we store the full history. Its a single global variable for everything that is recorded. This needs to be turned into a thread specific member. * I think the way GDB handles step means multiple threads will all be handled by a single record target, in a single thread. This needs to be verified, and if I'm right, we need to find a way to serialize the threads, so that we can replay thread in the correct order. * There's an open bug for gdb not properly handling (at least) sigtrap when an inferior is added: https://sourceware.org/bugzilla/show_bug.cgi?id=30025. We need to fix that if multiple processes are handled like multiple inferiors as you mentioned. Properly handling multi-threaded has been in my backlog for a bit, but I have one task for record that's much more important - adding support to AVX instructions - and I have limited time for record stuff, unfortunately. > Here there is only > one process > with multiple threads. I expect it to catch the segfault in thread 2 > but it fails > and goes into an infinite loop. Instead of a global variable, try using a counter on the while loops, and set it to a small value like 3-4. The current slowdown for execution is unbelievable (was also a backlogged thing for me). Also, I don't know if your system doesn't use a libc++ that's very optimized, but I can't record the creation of std::thread objects. That's because std::thread::_M_start_thread uses memset somewhere, and my glibc has the optimized avx512 version of memset, an instruction gdb can't disassemble yet. So we can add "supporting newer x86_64 instructions" to the list of tasks to do if we want to _properly_ support multi-threading. And if you want to double check what I mentioned above, I'd also recommend not printing, because that's also libc++, so likely to be using optimized instructions. -- Cheers, Guinevere Larsen She/Her/Hers > > #include<thread> > #include<iostream> > #include<unistd.h> > using namespace std; > bool run=true; > int i=6; > int *p=&i,g; > > void t1() { > while(run){ > g++; > if(g>=16) > p=nullptr; > cout <<"t1 "<<g<<endl; > } > } > > void t2(){ > int t=0; > while(run){ > g++; > t=*p + 5; > cout <<"t2 "<<g<<endl; > } > } > > > int main(){ > thread x1{t1},x2{t2}; > sleep(5); > run=false; > x1.join();x2.join(); > } > > > Regards, > Navin >