2012-02-01 3 views
1

Следующий код:недопустимый размер чтения в strcasestr

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

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

дает следующее сообщение об ошибке в 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) 

Кто-нибудь еще видел это? Это происходит с & без оптимизации, используя gcc 4.6.1.

+0

Я не могу воспроизвести эту проблему. Кстати, вы забыли макрос, который позволяет эти расширения, например. '#define _GNU_SOURCE'. –

+0

Что такое версия valgrind, можете ли вы повторить попытку с последней версией valgrind? – ouah

+0

@KerrekSB Используя GCC 4.6.1, вы не можете воспроизвести это? Я пробовал более ранние версии (4.5, 4.2, 4.1), и это не проблема. Что касается его использования в реальном мире, где я впервые обнаружил проблему, я использую g ++, который определяет _GNU_SOURCE - это всего лишь простой фрагмент для воспроизведения, который будет компилироваться. – nevelis

ответ

2

Если это происходит только в valgrind, это не ошибка. Было бы неопределенным поведением для ваш код для чтения за пределами объекта, полученного malloc, но strcasestr является частью «реализации» и поэтому может использовать знания, специфичные для реализации: в этом случае тот факт, что перечитывание абсолютно безопасен, если вы не пересекаете границу страницы.

+0

Кажется, все в порядке со значениями в кратных 16. После поиска в emmintrin.h: 685 в "return (__m128i) __builtin_ia32_loaddqu ((char const *) __ P)", похоже, что они загружают 16 байтов за раз , Я предполагаю, что C lib знает, что он делает: D спасибо за понимание. – nevelis