Hi everyone,

I am sending a 3 patch series to address the concerns, Thank you very much for the review. Here are my thoughts.

>> per step when program has atleast 3 or more threads running. A simple
>> walk through a function took around a minute. In compiler codes this is
>> slow.
>>
>> TO measure this properly I wrote a benchmark pasted below. The program spawns
>> 20 worker threads , then stops inside a function with 10 simple
>> that GDB steps over one by one. The GDB batch script breaks at that

>Seems to be missing a word after "simple".  Statements?

Made the corrections.


>> None of this work is wrong but it is needed when threads actually come
>> and go.  But during a next or step sequence through a function, the
>> thread list does not change. Paying for a full rescan on every stop is
>> something not needed I think.

>I mean, it *could* change, you could do "next" over a function that
>spawns a thread, a background thread (one other than the one you step)
>could spawn a thread, another thread could have exited, etc.

Yes, in the v3 version I have handle this. GDB resumes all threads (to let the callee execute), using ptid.tid() == 0. That path in resume() sets last_resume_step = 0. So when the return-address breakpoint fires, step_stop = false and the full sync runs and any new thread is caught.


>It's unrelated to this patch, but I happen to be looking at aix-thread.c
>because of it and I must ask if these things are still relevant, given
>the AIX versions and configurations you support nowadays:

The first patch in the coming series addresses these. Thanks for pointing out.

>Ulrich already pointed out that you could have one thread appear and one
>disappear, and the count will not change.

Yes, this is something I did not think. Thanks to both of you. The v3 patch implementation is based on single step only.  No thread counts used. 

>So yeah, what about doing "next" over a call that spawns a thread, or a
>background thread existing while you do a next?

The fix is safe for both scenarios because step_stop=true is only set when software single-step breakpoints were inserted for the resumed thread which means GDB knows the thread executed exactly one instruction and could not have called pthread_create or pthread_exit. For next over a function call that spawns a thread, GDB resumes all threads (ptid.tid()==0), which explicitly clears last_resume_step=0 at line 1087, so step_stop is never true and sync_threadlists() runs in full, picking up the new thread. For a background thread exiting during next, the single-step skips only apply to the internal one-instruction steps of the stepped thread; as soon as GDB resumes all threads for the next source-line boundary it clears last_resume_step=0, so the following stop calls sync_threadlists() and detects the exit. In both cases sync_threadlists() is always called on any stop where thread population could have changed. The optimization only fires for stops that are pure single-step traps of a single thread. No new thread can be created or destroyed in one instruction, so skipping the session update on those stops is correct. This is what my thought process is.


>> +/* Number of thread descriptors to fetch per getthrds() call.  The original
>> +   code fetched one at a time, which costs one syscall per thread.  Fetching
>> +   in batches reduces that to one syscall per GETTHRDS_BATCH threads.  */

>No need to document what the original code did.  Just keep the first
>sentence.

Sure, corrected the same in second patch of the coming series.


>> +#define GETTHRDS_BATCH 64
>Prefer:
>constexpr int GETTHRDS_BATCH = 64;

Done this in v3 version of the patch.

>> +
>>  /* Search through the list of all kernel threads for the thread
>>     that has stopped on a SIGTRAP signal, and return its TID.
>>     Return 0 if none found.  */
>This predates your patch, but is the comment for the get_signaled_thread
>function accurate?  It says it looks for a thread that has stopped on a
>SIGTRAP signal, but the implementation seems to look for any signal, not
>just SIGTRAP.

I have corrected this.


>> -  while (1)
>> +  while ((count = getthrds (pid, thrinf, sizeof (thrinf[0]),
>> +                         &ktid, GETTHRDS_BATCH)) > 0)

>>Prefer declaring the variable in the while statement, and separating the
>>comparison from the assignment.  This should work:

 >> while (int count = getthrds (pid, thrinf, sizeof (thrinf[0]), &ktid,
  >>                            GETTHRDS_BATCH));
  >>       count > 0)

>>     {

>> +      for (i = 0; i < count; i++)
>> +     if (thrinf[i].ti_cursig)
>> +       return thrinf[i].ti_tid;

>Declare variable `i` in the for loop.

The above two are addressed in v3 version of this patch. Simon, that works with for loop and not with while. 

Have a nice day ahead. 

Thanks and regards,
Aditya.