ErwinM February 2016

why is memmove garbling first few bytes

I am writing a hobbyOS. I want to copy a small section of memory from 1 spot to another. Somehow my memmove function keeps garbling the first few bytes and only the first few bytes.

This is my memmove function:

void* memmove(void *dst, const void *src, uint32_t n)
{
  const char *s;
  char *d;

  s = src;
  d = dst;
  if(s < d && s + n > d){
    s += n;
    d += n;
    while(n-- > 0)
      *--d = *--s;
  } else
    while(n-- > 0)
      *d++ = *s++;

  return dst;
}

I then call the function like so:

char *dest
char *origin    
memmove(dest, origin, 100);

When I inspect the memory after (i am using Boschs) I get this odd discrepancy in the first few bytes, everything after is copied as expected:

original at 0x502220:
0x0000000000502220 <bogus+       0>:    0x50224468  0x223c6800  0x006a0050

copy at 0x0:
0x0000000000000000 <bogus+       0>:    0x00504460  0x223c6800  0x006a0050

As you can see, only the first 4 bytes are garbled. The rest is copied as expected.

What is causing this behavior?

Answers


chux February 2016

  1. Following is UB. Cannot reliably compare with < <= >= > 2 pointers that are not of the same array, object.

    if(s < d && s + n > d){
    

When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object,... If the objects pointed to are members of the same aggregate object, ... All pointers to members of the same union object ... In all other cases, the behavior is undefined.
C11dr ยง6.5.8 5 Relational operators

  1. It is more canonical to use size_t n rather than uint32_t n.

  2. In the below usage, both dest, src are not initialized @Bathsheba delted answer. Based on user info, it appear code attempted to write to address 0. Likely the system prevents that. But it is UB using uninitialized pointers.

    char *dest
    char *origin    
    memmove(dest, origin, 100);
    


ErwinM February 2016

Turned out the memmove was succeeding without faults, but a concurrent (faulty) process was thrashing the first 4 bytes. I should have tested that better.

Thank you for all your answers.

Post Status

Asked in February 2016
Viewed 2,443 times
Voted 7
Answered 2 times

Search




Leave an answer