Okay, so now I learned about setting the frame and disassemble and see the 
memmove code:

Dump of assembler code for function memmove:
   0x00007ff96ba81220 <+0>:     mov    %rsi,0x8(%rsp)
   0x00007ff96ba81225 <+5>:     mov    %rdi,0x10(%rsp)
   0x00007ff96ba8122a <+10>:    mov    %rcx,%rdi
   0x00007ff96ba8122d <+13>:    mov    %rdx,%rsi
   0x00007ff96ba81230 <+16>:    mov    %r8,%rdx
   0x00007ff96ba81233 <+19>:    mov    %rdx,%rcx
   0x00007ff96ba81236 <+22>:    mov    %rdi,%rax
   0x00007ff96ba81239 <+25>:    mov    %rdi,%r11
   0x00007ff96ba8123c <+28>:    mov    %rdi,%r8
   0x00007ff96ba8123f <+31>:    sub    %rsi,%r8
   0x00007ff96ba81242 <+34>:    shr    $0x3,%rcx
   0x00007ff96ba81246 <+38>:    je     0x7ff96ba812bb <memmove+155>
   0x00007ff96ba81248 <+40>:    lea    -0x8(%rdi,%rdx,1),%r9
   0x00007ff96ba8124d <+45>:    mov    -0x8(%rsi,%rdx,1),%r10
   0x00007ff96ba81252 <+50>:    cmp    %rdx,%r8
   0x00007ff96ba81255 <+53>:    jb     0x7ff96ba8129e <memmove+126>
   0x00007ff96ba81257 <+55>:    and    $0x7,%r11
   0x00007ff96ba8125b <+59>:    jne    0x7ff96ba8126e <memmove+78>
   0x00007ff96ba8125d <+61>:    rep movsq %ds:(%rsi),%es:(%rdi)
   0x00007ff96ba81260 <+64>:    mov    %r10,(%r9)
   0x00007ff96ba81263 <+67>:    mov    0x8(%rsp),%rsi
   0x00007ff96ba81268 <+72>:    mov    0x10(%rsp),%rdi
   0x00007ff96ba8126d <+77>:    ret
   0x00007ff96ba8126e <+78>:    lea    -0x9(%r11,%rdx,1),%rcx
   0x00007ff96ba81273 <+83>:    neg    %r11
   0x00007ff96ba81276 <+86>:    mov    (%rsi),%rdx
   0x00007ff96ba81279 <+89>:    mov    %rdi,%r8
   0x00007ff96ba8127c <+92>:    lea    0x8(%rsi,%r11,1),%rsi
   0x00007ff96ba81281 <+97>:    lea    0x8(%rdi,%r11,1),%rdi
   0x00007ff96ba81286 <+102>:   shr    $0x3,%rcx
   0x00007ff96ba8128a <+106>:   rep movsq %ds:(%rsi),%es:(%rdi)
   0x00007ff96ba8128d <+109>:   mov    %rdx,(%r8)
   0x00007ff96ba81290 <+112>:   mov    %r10,(%r9)
   0x00007ff96ba81293 <+115>:   mov    0x8(%rsp),%rsi
   0x00007ff96ba81298 <+120>:   mov    0x10(%rsp),%rdi
   0x00007ff96ba8129d <+125>:   ret
   0x00007ff96ba8129e <+126>:   lea    -0x8(%rsi,%rcx,8),%rsi
   0x00007ff96ba812a3 <+131>:   lea    -0x8(%rdi,%rcx,8),%rdi
   0x00007ff96ba812a8 <+136>:   std
=> 0x00007ff96ba812a9 <+137>:   rep movsq %ds:(%rsi),%es:(%rdi)
   0x00007ff96ba812ac <+140>:   cld
   0x00007ff96ba812ad <+141>:   mov    %r10,(%r9)
   0x00007ff96ba812b0 <+144>:   mov    0x8(%rsp),%rsi
   0x00007ff96ba812b5 <+149>:   mov    0x10(%rsp),%rdi
   0x00007ff96ba812ba <+154>:   ret
   0x00007ff96ba812bb <+155>:   mov    %rdx,%rcx
   0x00007ff96ba812be <+158>:   cmp    %rdx,%r8
   0x00007ff96ba812c1 <+161>:   jb     0x7ff96ba812d0 <memmove+176>
   0x00007ff96ba812c3 <+163>:   rep movsb %ds:(%rsi),%es:(%rdi)
   0x00007ff96ba812c5 <+165>:   mov    0x8(%rsp),%rsi
   0x00007ff96ba812ca <+170>:   mov    0x10(%rsp),%rdi
   0x00007ff96ba812cf <+175>:   ret
   0x00007ff96ba812d0 <+176>:   lea    -0x1(%rsi,%rcx,1),%rsi
   0x00007ff96ba812d5 <+181>:   lea    -0x1(%rdi,%rcx,1),%rdi
   0x00007ff96ba812da <+186>:   std
   0x00007ff96ba812db <+187>:   rep movsb %ds:(%rsi),%es:(%rdi)
   0x00007ff96ba812dd <+189>:   cld
   0x00007ff96ba812de <+190>:   mov    0x8(%rsp),%rsi
   0x00007ff96ba812e3 <+195>:   mov    0x10(%rsp),%rdi
   0x00007ff96ba812e8 <+200>:   ret
   0x00007ff96ba812e9 <+201>:   nop
   0x00007ff96ba812ea <+202>:   nop
   0x00007ff96ba812eb <+203>:   nop
   0x00007ff96ba812ec <+204>:   nop
   0x00007ff96ba812ed <+205>:   nop
   0x00007ff96ba812ee <+206>:   nop
   0x00007ff96ba812ef <+207>:   nop
End of assembler dump.

Now I need to figure out how to view the ds, rsi, es, rdi, and rcx(?) register 
values.....


> On 02/25/2026 10:22 PM PST KENNON J CONRAD via Cygwin <[email protected]> 
> wrote:
> 
>  
> Hi Brian,
> 
>    I installed the version of the cygwin-debuginfo that is on my test 
> computer to the build machine (version 3.6.6-1).  I put the memmove back in 
> the code in place of the bloated code that has been running the past 4 days 
> without any problem (and the past ~10 years before changing to memmove) and 
> got another SIGTRAP in gbd on that memset within 2 hours.  The backtrace 
> looks very similar:
> 
> #0  0x00007ff97e40a98b in KERNELBASE!DebugBreak () from 
> /cygdrive/c/Windows/system32/KERNELBASE.dll
> No symbol table info available.
> #1  0x00007ff96ba86417 in cygwin1!.assert () from 
> /cygdrive/c/Windows/cygwin1.dll
> No symbol table info available.
> #2  0x00007ff96ba9fb18 in secure_getenv () from 
> /cygdrive/c/Windows/cygwin1.dll
> No symbol table info available.
> #3  0x00007ff980c5d82d in ntdll!.chkstk () from 
> /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> No symbol table info available.
> #4  0x00007ff980c0916b in ntdll!RtlRaiseException () from 
> /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> No symbol table info available.
> #5  0x00007ff980c5c9ee in ntdll!KiUserExceptionDispatcher () from 
> /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> No symbol table info available.
> #6  0x00007ff96ba812a9 in memmove () from /cygdrive/c/Windows/cygwin1.dll
> No symbol table info available.
> #7  0x00000001004099ec in rank_scores_thread (arg=0x6ffecf1c0010) at 
> GLZAcompress.c:854
>         new_score_rank = 767
>         new_score_lmi2 = 333188156
>         new_score_pmi2 = 333188149
>         rank = 3360
>         max_rank = 767
>         num_symbols = 7
>         new_score_lmi = 332397489
>         new_score_pmi = 332397482
>         thread_data_ptr = 0x6ffecf1c0010
>         max_scores = 3361
>         candidates_index = 0xa00034460
>         score_index = 3319
>         node_score_num_symbols = 14
>         num_candidates = 3361
>         node_ptrs_num = 49710
>         local_write_index = 49711
>         rank_scores_buffer = 0x6ffecf1c0020
>         candidates = 0x6ffecf2c0020
>         score = 50.3955727
> #8  0x00007ff96bae2eec in cygwin1!.getreent () from 
> /cygdrive/c/Windows/cygwin1.dll
> No symbol table info available.
> #9  0x00007ff96ba847d3 in cygwin1!.assert () from 
> /cygdrive/c/Windows/cygwin1.dll
> No symbol table info available.
> #10 0x0000000000000000 in ?? ()
> No symbol table info available.
> 
> candidates_index is 0x10 less than it was in the previously mentioned 
> SIGTRAP.  Not surprising, I made some minor unrelated code changes.
> 
> This time, it should be moving the values in candidates index values 
> (uint16_t's) to an address that is 2 bytes larger starting at index 3359 and 
> ending at index 767 (vs. starting at 4379 and ending at index 2633 in the 
> previously mentioned SIGTRAP).
> 
> Unfortunately, I am not seeing any additional information to make debugging 
> the SIGTRAP in memmove easier.  Was I supposed to install additional packages 
> to debug memmove?  Are there commands in gbd to explore what happened with 
> the memmove?  Any further help in debugging this problem would be greatly 
> appreciated.  Unless there is more information available through gdb it seems 
> the best option may be to make a simplified test program that exhibits the 
> problem.
> 
> On the bright side, I am gaining confidence that the GLZA program is robust 
> as long as it does not use memmove in this location.  It would have taken 
> much longer to track this down without the gdb included in the Cygwin 
> package.  I would have assumed memmove is a robust command when all the 
> evidence I have gathered indicates it is not robust in this use case.  I 
> could just let it go, but feel there is a strong possibility that there is a 
> bug in memmove that needs further investigation.  If my coding skills were 
> better, I might know how to proceed, but right now I'm kind of stuck in that 
> regard.  It seems it would be best to investigate the memmove code but I have 
> not been able to locate it in the install package or find a way to get gdb to 
> print useful information for functions in the library.  Any ideas?
> 
> Best Regards,
> 
> Kennon
> 
> 
> 
> > On 02/25/2026 10:28 AM PST Brian Inglis via Cygwin <[email protected]> 
> > wrote:
> > 
> >  
> > Hi Kennon,
> > 
> > To make debugging easier and more informative with source and symbols 
> > install 
> > the cygwin-debuginfo package, similarly with any other library 
> > dependencies, or 
> > other package binaries.
> > 
> > On 2026-02-25 11:18, KENNON J CONRAD via Cygwin wrote:
> > > new_score_rank is a local variable.  GDB only prints local variables.  No 
> > > other thread can access this local variable.
> > > 
> > > Best Regards,
> > > 
> > > Kennon
> > > 
> > >> On 02/25/2026 2:32 AM PST Duncan Roe via Cygwin <[email protected]> 
> > >> wrote:
> > >>
> > >>   
> > >> Hi Kennon,
> > >>
> > >> On Tue, Feb 24, 2026 at 10:38:01AM -0800, cygwin wrote:
> > >>> Hello,
> > >>>
> > >>>     I am having a problem with that is apparently related to memmove 
> > >>> and looking for some advice on how to investigate further.  This winter 
> > >>> I have been working to simplify GLZA source code and make it more 
> > >>> readable.  GLZA is an advanced open source code straight line grammar 
> > >>> compressor first released in 2015.  Among these changes was replacing 
> > >>> some rather bloated code with memmove and memset in various locations.  
> > >>> The program started crashing occassionally and after extensively 
> > >>> reviewing the changes, I was unable to find a cause for these crashes.  
> > >>> So I installed gdb to try to find out what was going on and was 
> > >>> apparently able to find the cause of the problem.  As a new gdb user, I 
> > >>> am not very comfortable with trusting the results of what gdb showing, 
> > >>> but it is pointing directly to one of the code changes I made.  I 
> > >>> backed out of this code change and the program has not crashed after 3 
> > >>> days of nearly continuous testing.
> > >>>
> > >>>     So here is what gdb reports when backtrace is run immediately after 
> > >>> reporting a "SIGTRAP":
> > >>>
> > >>> (gdb) bt full
> > >>> #0 0x00007ff9dd8aa98b in KERNELBASE!DebugBreak () from 
> > >>> /cygdrive/c/Windows/system32/KERNELBASE.dll
> > >>> No symbol table info available.
> > >>> #1 0x00007ff9ca3b6417 in cygwin1!.assert () from 
> > >>> /cygdrive/c/Windows/cygwin1.dll
> > >>> No symbol table info available.
> > >>> #2 0x00007ff9ca3cfb18 in secure_getenv () from 
> > >>> /cygdrive/c/Windows/cygwin1.dll
> > >>> No symbol table info available.
> > >>> #3 0x00007ff9e03dd82d in ntdll!.chkstk () from 
> > >>> /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> > >>> No symbol table info available.
> > >>> #4 0x00007ff9e038916b in ntdll!RtlRaiseException () from 
> > >>> /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> > >>> No symbol table info available.
> > >>> #5 0x00007ff9e03dc9ee in ntdll!KiUserExceptionDispatcher () from 
> > >>> /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> > >>> No symbol table info available.
> > >>> #6 0x00007ff9ca3b12a9 in memmove () from /cygdrive/c/Windows/cygwin1.dll
> > >>> No symbol table info available.
> > >>> #7 0x0000000100409a7c in rank_scores_thread (arg=0x6ffece890010) at 
> > >>> GLZAcompress.c:904
> > >>> new_score_rank = 2633
> > >>> new_score_lmi2 = 183964750
> > >>> new_score_pmi2 = 183964725
> > >>> rank = 4380
> > >>> max_rank = 2633
> > >>> num_symbols = 25
> > >>> new_score_lmi = 92079851
> > >>> new_score_pmi = 92079826
> > >>> thread_data_ptr = 0x6ffece890010
> > >>> max_scores = 4883
> > >>> candidates_index = 0xa00034470
> > >>> score_index = 4380
> > >>> node_score_num_symbols = 7
> > >>> num_candidates = 4381
> > >>> node_ptrs_num = 12224
> > >>> local_write_index = 12225
> > >>> rank_scores_buffer = 0x6ffece890020
> > >>> candidates = 0x6ffece990020
> > >>> score = 47.6283531
> > >>> #8 0x00007ff9ca412eec in cygwin1!.getreent () from 
> > >>> /cygdrive/c/Windows/cygwin1.dll
> > >>> No symbol table info available.
> > >>> #9 0x00007ff9ca3b47d3 in cygwin1!.assert () from 
> > >>> /cygdrive/c/Windows/cygwin1.dll
> > >>> No symbol table info available.
> > >>> #10 0x0000000000000000 in ?? ()
> > >>> No symbol table info available.
> > >>>
> > >>> GLZAcompress.c line 904 is as follows and is in code that runs as a 
> > >>> separate thread created in main:
> > >>> memmove(&candidates_index[new_score_rank+1], 
> > >>> &candidates_index[new_score_rank], 2 * (rank - new_score_rank));
> > >>> This does point directly to where a code change was made.
> > >>>
> > >>> candidates_index is allocated in main and not ever intentionally 
> > >>> changed until deallocated at the end of program execution:
> > >>> if (0 == (candidates_index = (uint16_t *)malloc(max_scores * 
> > >>> sizeof(uint16_t))))
> > >>>    fprintf(stderr, "ERROR - memory allocation failed\n");
> > >>> This value is passed to the thread in a structure pointed to by the 
> > >>> thread arg.  The value 0xa00034470 for candidates_index is similar to 
> > >>> what is reported on subsequent runs with added code to print this value 
> > >>> so I don't think it's corrupted, but would need to duplicate the crash 
> > >>> after checking the initial value to be 100% certain.  With gdb 
> > >>> reporting that rank = 4380 and new_score_rank = 2633 at the time of the 
> > >>> SIGTRAP, this should be a backward move of 1747 uint16_t values by 2 
> > >>> bytes with a 2 byte difference between the source and destination 
> > >>> addresses.
> > >>>
> > >>> Prior to this code change and for the last 3 days I have been using 
> > >>> this code instead and not seen any crashes:
> > >>> uint16_t * score_ptr = &candidates_index[new_score_rank];
> > >>> uint16_t * candidate_ptr = &candidates_index[rank];
> > >>> while (candidate_ptr >= score_ptr + 8) {
> > >>>   *candidate_ptr = *(candidate_ptr - 1);
> > >>>   *(candidate_ptr - 1) = *(candidate_ptr - 2);
> > >>>   *(candidate_ptr - 2) = *(candidate_ptr - 3);
> > >>>   *(candidate_ptr - 3) = *(candidate_ptr - 4);
> > >>>   *(candidate_ptr - 4) = *(candidate_ptr - 5);
> > >>>   *(candidate_ptr - 5) = *(candidate_ptr - 6);
> > >>>   *(candidate_ptr - 6) = *(candidate_ptr - 7);
> > >>>   *(candidate_ptr - 7) = *(candidate_ptr - 8);
> > >>>   candidate_ptr -= 8;
> > >>> }
> > >>> while (candidate_ptr > score_ptr) {
> > >>>   *candidate_ptr = *(candidate_ptr - 1);
> > >>>   candidate_ptr--;
> > >>> }
> > >>> Yes, it's bloated code that should do the same thing as the memmove, 
> > >>> but most importantly the code has never caused any problems.  
> > >>> Interestingly, even this code shows memmove in the assembly code (gcc 
> > >>> -S), but only for the second while loop.  The looping code for the 
> > >>> first while loop looks like this and moves 8 uint16_t's in just 5 
> > >>> instruction so it is perhaps not as inefficient as the source code 
> > >>> looks:
> > >>> .L25:
> > >>> movdqu -16(%rax), %xmm1
> > >>> subq $16, %rax
> > >>> movups %xmm1, 2(%rax)
> > >>> cmpq %rdx, %rax
> > >>> jnb .L25
> > >>>
> > >>> It may or may not matter, but the code this is happening on is very CPU 
> > >>> intensive - there can be up to 8 threads running at the same time when 
> > >>> this problem occurs.  The problem doesn't occur consistently, it seems 
> > >>> to be rather random.  The program runs about 500 iterations of ranking 
> > >>> up to the top 30,000 new grammar rule candidates over nearly 4 hours on 
> > >>> my test case and has crashed on different iterations each time it has 
> > >>> crashed, even though the thread that seems to be crashing should be 
> > >>> seeing exactly the same data each time the program is run.  The 
> > >>> malloc'ed array address could be changing, I haven't checked that out.
> > >>>
> > >>> I find it really hard to believe there is a bug in memmove but that 
> > >>> seems to be what gdb and my testing are indicating.  So I am looking 
> > >>> for advice on how to better understand what is causing the program to 
> > >>> crash.  I would like to review the code memset is using, but have not 
> > >>> been able to figure out how to track that down.  Any help in 
> > >>> understanding what code the complier is using for memmove would be 
> > >>> helpful.  Are there other things I could possibly be overlooking?  Are 
> > >>> the any other things I should review or report that would be helpful?  
> > >>> I could try to write a simplified test case if that would be useful.
> > >>>
> > >>> Best Regards,
> > >>>
> > >>> Kennon Conrad
> > >>>
> > >>>
> > >>
> > >>>
> > >>> --
> > >>> Problem reports:      https://cygwin.com/problems.html
> > >>> FAQ:                  https://cygwin.com/faq/
> > >>> Documentation:        https://cygwin.com/docs.html
> > >>> Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple
> > >>
> > >> The memmove() call acceses new_score_rank 3 times while the old code only
> > >> accessed it once. Is it possible that another CPU alters new_score_rank 
> > >> between
> > >> these acesses?
> > >>
> > >> You could eliminate that possibility by making a local copy of 
> > >> new_score_rank
> > >> and using that in the memmove() call. Worth a try?
> > >>
> > >> Cheers ... Duncan.
> > >>
> > >> -- 
> > >> Problem reports:      https://cygwin.com/problems.html
> > >> FAQ:                  https://cygwin.com/faq/
> > >> Documentation:        https://cygwin.com/docs.html
> > >> Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple
> > > 
> > 
> > 
> > -- 
> > Take care. Thanks, Brian Inglis              Calgary, Alberta, Canada
> > 
> > La perfection est atteinte                   Perfection is achieved
> > non pas lorsqu'il n'y a plus rien à ajouter  not when there is no more to 
> > add
> > mais lorsqu'il n'y a plus rien à retrancher  but when there is no more to 
> > cut
> >                                  -- Antoine de Saint-Exupéry
> > 
> > -- 
> > Problem reports:      https://cygwin.com/problems.html
> > FAQ:                  https://cygwin.com/faq/
> > Documentation:        https://cygwin.com/docs.html
> > Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple
> 
> -- 
> Problem reports:      https://cygwin.com/problems.html
> FAQ:                  https://cygwin.com/faq/
> Documentation:        https://cygwin.com/docs.html
> Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to