0

I'm running some tests on a Cortex-R5 (Ultrascale MpSoC). It basically generates 2 random numbers with a hardware module and compares them at the end to ensure they're not 0, nor the same values.

   uint32_t status;
   const uint8_t zeros[32] = {0};
   uint8_t bytes1[32] = {0};
   uint8_t bytes2[32] = {0};

   // (generate random numbers and put them in bytes1)
   // (generate random numbers and put them in bytes2)

   printf("memcmp 0\n");
   status = !memcmp(bytes1, bytes2, 32);
   printf("memcmp 1\n");
   status |= !memcmp(bytes1, zeros, 32);
   printf("memcmp 2\n");
   status |= !memcmp(bytes2, zeros, 32);

Some tests are running fine. Some executions are stalled after printing "memcmp 0" (when it freezes, it's always at the first memcmp)...

I have tried several things:

  • When I print the values in bytes1 and 2, they are indeed random numbers not equal to 0 and not equal with each other.
  • Moving the memcmp at different places, or switching the memcmp's. It's always the first one which freezes.
  • Replacing memcmp with a custom function to do comparison => it never freezes.
  • The memcmp function is used at other places of the code and it freezes nowhere else. Perhaps the difference is that the random check is the only place where the memcmp expects different values (at other places it's to ensure a function produces expected output).

I couldn't find the definition of memcmp... I don't know where to look. The only thing I could find is the assembly code, but it'd be difficult to attach a debugger to know exactly which instruction can't complete.

000064d0 <memcmp>:
    64d0:   2a03        cmp r2, #3
    64d2:   b470        push    {r4, r5, r6}
    64d4:   d912        bls.n   64fc <memcmp+0x2c>
    64d6:   ea40 0501   orr.w   r5, r0, r1
    64da:   4604        mov r4, r0
    64dc:   07ad        lsls    r5, r5, #30
    64de:   460b        mov r3, r1
    64e0:   d120        bne.n   6524 <memcmp+0x54>
    64e2:   681d        ldr r5, [r3, #0]
    64e4:   4619        mov r1, r3
    64e6:   6826        ldr r6, [r4, #0]
    64e8:   4620        mov r0, r4
    64ea:   3304        adds    r3, #4
    64ec:   3404        adds    r4, #4
    64ee:   42ae        cmp r6, r5
    64f0:   d118        bne.n   6524 <memcmp+0x54>
    64f2:   3a04        subs    r2, #4
    64f4:   4620        mov r0, r4
    64f6:   2a03        cmp r2, #3
    64f8:   4619        mov r1, r3
    64fa:   d8f2        bhi.n   64e2 <memcmp+0x12>
    64fc:   1e54        subs    r4, r2, #1
    64fe:   b172        cbz r2, 651e <memcmp+0x4e>
    6500:   7802        ldrb    r2, [r0, #0]
    6502:   780b        ldrb    r3, [r1, #0]
    6504:   429a        cmp r2, r3
    6506:   bf08        it  eq
    6508:   1864        addeq   r4, r4, r1
    650a:   d006        beq.n   651a <memcmp+0x4a>
    650c:   e00c        b.n 6528 <memcmp+0x58>
    650e:   f810 2f01   ldrb.w  r2, [r0, #1]!
    6512:   f811 3f01   ldrb.w  r3, [r1, #1]!
    6516:   429a        cmp r2, r3
    6518:   d106        bne.n   6528 <memcmp+0x58>
    651a:   42a1        cmp r1, r4
    651c:   d1f7        bne.n   650e <memcmp+0x3e>
    651e:   2000        movs    r0, #0
    6520:   bc70        pop {r4, r5, r6}
    6522:   4770        bx  lr
    6524:   1e54        subs    r4, r2, #1
    6526:   e7eb        b.n 6500 <memcmp+0x30>
    6528:   1ad0        subs    r0, r2, r3
    652a:   bc70        pop {r4, r5, r6}
    652c:   4770        bx  lr
    652e:   bf00        nop
  1. Where can I see the source code of memcmp for cortex R5? FYI, the used compiler is armr5-none-eabi-gcc.
  2. Any idea what could cause a CPU stall with this function?

Thank you

Floha
  • 1
  • 1
    It rather sounds like a race condition bug, stack overflow or some such. This is almost certainly not related to memcmp but some non-related bug elsewhere. How do you populate those arrays? Any interrupts or multiple processes involved? – Lundin Feb 19 '20 at 12:49
  • I'd expect memcmp to be inlined. Did you `#include ` ? (also stdio.h, of course) – wildplasser Feb 19 '20 at 12:52
  • @Lundin They are indeed populated by a DMA in the programmable logic (PL) where the random generator is. What is strange is that the issue also appears when I first print the values of bytes1 and bytes2 before comparing... How could there be a race-condition after that? – Floha Feb 19 '20 at 12:55
  • @wildplasser Yes, I include it. – Floha Feb 19 '20 at 12:56
  • 1
    1) You need to protect the data from getting updated by the DMA while you are accessing it, otherwise there will be race condition hell. 2) All DMA buffers _must_ be `volatile` or otherwise the compiler's optimizer is free to do mighty strange things to them. This could very well be the case, since functions like memcmp are heavily optimized and almost always inlined. – Lundin Feb 19 '20 at 13:01
  • @Lundin 1) Normally the DMA should have finished writing data to the buffers when it gets out of the function (waiting for a status). 2) I admit volatile should be set, but the test still fails when specified. – Floha Feb 19 '20 at 14:30

0 Answers0