==11136== Invalid read of size 8
==11136== at 0x5AFC696: memrchr (memrchr.S:289)
==11136== by 0x5B57FAF: dirname (dirname.c:45)
==11136== by 0x405F43: push::lg_cmd_dirname(push::Env&) (LGExtension.cpp:379)
==11136== by 0x42533C: push::Instruction::operator()(push::Env&) const (in /home/bots/svn/eco/branches/skynet_BigPUSH/src/push3.0/extension/push_bloodline)
==11136== by 0x488ECD: push::Env::go(int) (Env.cpp:72)
==11136== by 0x4A84D5: main (bloodline.cpp:99)
==11136== Address 0x640daf8 is 8 bytes inside a block of size 10 alloc'd
==11136== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11136== by 0x5AEF801: strdup (strdup.c:43)
==11136== by 0x405EF2: push::lg_cmd_dirname(push::Env&) (LGExtension.cpp:369)
==11136== by 0x42533C: push::Instruction::operator()(push::Env&) const (in /home/bots/svn/eco/branches/skynet_BigPUSH/src/push3.0/extension/push_bloodline)
==11136== by 0x488ECD: push::Env::go(int) (Env.cpp:72)
==11136== by 0x4A84D5: main (bloodline.cpp:99)
==11136==
Это законная ошибка? Похоже, что чтение происходит внутри допустимого блока. В моей программе вызов выглядит так:
char *path = strdup(full_path.c_str());
cerr << "Path is : " << path << endl;
result = dirname(path);
if(result < 0){
cerr << "Dirname failed for some reason. Check log." << endl;
}
и вывод к cerr во время ошибки:
Path is : /tmp/tmp/
который является допустимым путем. У Dirname не должно быть проблем с этим, и он работает с кучей выделенных дубликатов.
РЕДАКТИРОВАТЬ:
Вот минимальный пример, который выдаст эту ошибку:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <libgen.h>
int main(){
char *path = strdup("/tmp/tmp/");
char* result = dirname(path);
std::cerr << result << std::endl;
}
скомпилировать с g ++.
запустить с Valgrind, и вы получите:
==32466== Memcheck, a memory error detector
==32466== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==32466== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==32466== Command: ./a.out
==32466==
==32466== Invalid read of size 8
==32466== at 0x51C7696: memrchr (memrchr.S:289)
==32466== by 0x5222FAF: dirname (dirname.c:45)
==32466== by 0x400865: main (in /home/j3doucet/a.out)
==32466== Address 0x59ff048 is 8 bytes inside a block of size 10 alloc'd
==32466== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32466== by 0x51BA801: strdup (strdup.c:43)
==32466== by 0x400855: main (in /home/j3doucet/a.out)
==32466==
/tmp
==32466==
==32466== HEAP SUMMARY:
==32466== in use at exit: 10 bytes in 1 blocks
==32466== total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==32466==
==32466== LEAK SUMMARY:
==32466== definitely lost: 10 bytes in 1 blocks
==32466== indirectly lost: 0 bytes in 0 blocks
==32466== possibly lost: 0 bytes in 0 blocks
==32466== still reachable: 0 bytes in 0 blocks
==32466== suppressed: 0 bytes in 0 blocks
==32466== Rerun with --leak-check=full to see details of leaked memory
==32466==
==32466== For counts of detected and suppressed errors, rerun with: -v
==32466== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Valgrind указывает, что чтение размера 8 выполняется из байта номер 8 в
блок из 10 байтов.
Это чтение сделано memrchr.
Такие функции часто оптимизируются исходя из предположения, что вы можете прочитать
больше байтов, чем выделенный блок.
Чтобы избежать сообщения о таких проблемах, Valgrind должен заменить такие оптимизированные
функции своей собственной переопределяющей функцией.
memrchr был переопределен только в Valgrind начиная с версии 3.8.
=> вам следует повторить попытку с последней версией Valgrind (3.8.1).
В этом случае ошибка может больше не сообщаться (при условии, что она фактически является ложноположительной
из-за не переопределения memrchr).
Других решений пока нет …