1

The following code:

#include <stdlib.h>
#include <string.h>

int main() {
    char *s = strdup("keep-alive");
    if(strcasestr(s, "close")) {
    }
    free(s);
    return 0;
}

gives the following error in Valgrind:

==13183== Invalid read of size 8
==13183==    at 0x4F53F94: __strcasestr_sse42 (emmintrin.h:685)
==13183==    by 0x4005BF: main (in /home/aaron/dev/strtest)
==13183==  Address 0x51ce048 is 8 bytes inside a block of size 11 alloc'd
==13183==    at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==13183==    by 0x4EB1441: strdup (strdup.c:43)
==13183==    by 0x4005A5: main (in /home/aaron/dev/strtest)

Has anyone else seen this? This happens with & without optimizations, using gcc 4.6.1.

nevelis
  • 736
  • 6
  • 17
  • I cannot reproduce this problem. By the way, you forgot a macro that enables those extensions, e.g. `#define _GNU_SOURCE`. – Kerrek SB Feb 01 '12 at 00:17
  • what is the version of valgrind, can you retry with the last version of valgrind? – ouah Feb 01 '12 at 00:19
  • @KerrekSB Using GCC 4.6.1 you cannot reproduce this? I have tried on earlier versions (4.5, 4.2, 4.1) & it's not an issue. As for its use in the real world where I first discovered the problem, I'm using g++ which defines _GNU_SOURCE - this is merely a bare snippet to reproduce that will compile. – nevelis Feb 01 '12 at 00:28
  • I can reproduce this with gcc 4.6.1 and Valgrind-3.6.1-Debian – Timothy Jones Feb 01 '12 at 00:37
  • Nope, I cannot; both with gcc and with g++, 4.6.2, and valgrind 3.6.0. It just works fine. – Kerrek SB Feb 01 '12 at 00:42
  • @KerrekSB What kind of CPU do you have? a Core 2 or lower you wouldn't see this. – nevelis Feb 01 '12 at 01:51
  • @nevelis: I think I I have a Core Duo. How weird that this should depend on the CPU...! – Kerrek SB Feb 01 '12 at 02:16

1 Answers1

2

If this is only happening in valgrind, it's not an error. It would be undefined behavior for your code to read beyond the end of an object obtained by malloc, but strcasestr is part of "the implementation" and thus can use implementation-specific knowledge: in this case, the fact that over-reading is perfectly safe as long as you don't cross a page boundary.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • It seems to be okay with values in multiples of 16. After looking in emmintrin.h:685 at "return (__m128i) __builtin_ia32_loaddqu ((char const *)__P)", it looks like they're loading 16 bytes at a time. I'll assume the C lib knows what it's doing :D thanks for the insight. – nevelis Feb 01 '12 at 00:42