나는이 문제로 언젠가 고투하고 있으며,이 누출이 일어나는 이유를 찾을 수 없다.double free or corruption (! prev) 나는 왜 C 언어가 가능한지 알 수 없다.
내가 가장하는 것은 eb와 db를 fileblock으로 주문하는 것입니다. 그래서 먼저 eb와 db 메모리 조각으로 fileblock을 주문합니다. 이 후 구조에 저장된이 데이터를 db, eb 및 fileblock에 복사하려고합니다. 따라서 중간 구조의 데이터를 사용하여 데이터의 순서를 변경하기 만하면됩니다.
나는 여기에 코드를 붙여 넣은 후 그 문제와 테스트가 내가 수행 한 깊이 더 설명 :
struct reorder_blocks_s
{
int64_t pos;
int64_t originalPos;
int64_t nextPos;
int64_t newSeekLenPos;
int64_t ctrl[3];
uint8_t *dataBlock;
uint8_t *extraBlock;
};
static void initReorderBlocks (struct reorder_blocks_s *structure,
uint64_t size)
{
memset(structure, 0, sizeof(struct reorder_blocks_s));
}
static void reorderBlocks (uint8_t *fileblock, uint8_t *db, uint8_t *eb,
int64_t ctrllen, int64_t dblen, int64_t eblen,
int64_t newsize)
{
uint32_t count = 0;
int64_t ctrl[3];
int64_t ctrl2[3];
uint8_t *auxFileblock = fileblock;
uint8_t *auxDb = db;
uint8_t *auxEb = eb;
uint8_t buf[8];
uint16_t problematicCount = 0;
uint64_t currentPos = 0;
uint32_t maxToSave = 0;
bool firstTime = true;
struct reorder_blocks_s *newFileBlock;
newFileBlock = malloc (sizeof(struct reorder_blocks_s) *
(ctrllen/24) + 1);
struct reorder_blocks_s *problematicFields;
problematicFields = malloc (sizeof(struct reorder_blocks_s) *
(ctrllen/24) + 1);
struct reorder_blocks_s * auxProblematicFields;
int64_t *bytesNeededToSave = malloc(sizeof(int64_t)*(ctrllen/24));
struct reorder_blocks_s auxReorderStructure;
struct reorder_blocks_s auxProblematicStructure;
/* Init the structures. */
initReorderBlocks(newFileBlock, ctrllen/24);
initReorderBlocks(&auxReorderStructure, 1);
/* First it would be needed to go throght fileblock (ctrlblock) storing all
* the data in the structure to be arranged.
*/
// printf("ctrllen, dblen, eblen: %ld, %ld, %ld\n", ctrllen, dblen, eblen);
//
//printf("Imprimo los newFileBlock SIN ORDENAR\n");
//
//printf("Direccion de memoria de db:%ld\n", db);
//printf("Direccion de memoria de eb:%ld\n", eb);
uint32_t dbSUM = 0;
uint32_t ebSUM = 0;
for (int64_t i = 0; i < ctrllen/24; i++)
{
ctrl[0] = offtin(fileblock);
ctrl[1] = offtin(fileblock+8);
ctrl[2] = offtin(fileblock+16);
if(ctrl[0] != 0)
newFileBlock[i].dataBlock = malloc(sizeof(uint8_t) * ctrl[0]);
else
newFileBlock[i].dataBlock = NULL;
if(ctrl[1] != 0)
newFileBlock[i].extraBlock = malloc(sizeof(uint8_t) * ctrl[1]);
else
newFileBlock[i].dataBlock = NULL;
if (firstTime)
{
newFileBlock[i].originalPos = 0;
firstTime = false;
}
else
newFileBlock[i].originalPos = currentPos;
newFileBlock[i].pos = count;
/* Copy ctrl 24 bytes into the structure field ctrl. */
memcpy(&(newFileBlock[i].ctrl), ctrl, sizeof(int64_t) * 3);
if(newFileBlock[i].dataBlock != NULL)
memcpy(newFileBlock[i].dataBlock, db, sizeof(uint8_t) * ctrl[0]);
if(newFileBlock[i].extraBlock != NULL)
memcpy(newFileBlock[i].extraBlock, eb, sizeof(uint8_t) * ctrl[1]);
if(memcmp(newFileBlock[i].extraBlock, eb, sizeof(uint8_t) * ctrl[1]))
{
printf("ERROR GRRRRR\n");
exit(0);
}
// printf("ctrl[0]: %ld\t ctrl[1]: %ld\t ctrl[2]: %ld\t y posicion de memoria \
// original: %ld\n", newFileBlock[i].ctrl[0], newFileBlock[i].ctrl[1]
// , newFileBlock[i].ctrl[2], newFileBlock[i].originalPos);
db += ctrl[0];
eb += ctrl[1];
currentPos += ctrl[0] + ctrl[2];
fileblock += 24;
count++;
dbSUM += ctrl[0];
ebSUM += ctrl[1];
}
/* fileblock pointer pointing to the memory initial address of ctrl block. */
fileblock = auxFileblock;
/* Restore db and eb pointers to their initial addresses. */
// printf("ANTES DE RESTORE. Direccion de memoria de db: %ld\n", db);
// printf("ANTES DE RESTORE. Direccion de memoria de eb: %ld\n", eb);
db = auxDb;
eb = auxEb;
// printf("Direccion de memoria de db :%ld\n", db);
// printf("Direccion de memoria de eb: %ld\n", eb);
// printf("dbSUM: %ld\n", dbSUM);
// printf("ebSUM: %ld\n", ebSUM);
/* Once the data has been stored its is time to order all the structure,
* modifiying from the lower address to the higher one.
*/
for (int64_t i = 0; i < ctrllen/24; ++i)
{
for (int64_t j = i + 1; j < ctrllen/24; ++j)
{
if ((newFileBlock[i].originalPos > newFileBlock[j].originalPos))
{
memcpy(&auxReorderStructure, &newFileBlock[i], sizeof(struct reorder_blocks_s));
memcpy(&newFileBlock[i], &newFileBlock[j], sizeof(struct reorder_blocks_s));
memcpy(&newFileBlock[j], &auxReorderStructure, sizeof(struct reorder_blocks_s));
}
}
}
/* Clean the data block and the extra block is recommended before setting
* them again.FAILING IF I USE IT!!!!
*/
//why are those memsets affecting the code!!!
// memset(db, 0x00, newsize + 1);
// memset(eb, 0x00, newsize + 1);
// for (int64_t i = 0; i < dblen + 1; i++)
// {
// *db = 0x00;
// db += 1;
// }
//
// for (int64_t i = 0; i < eblen + 1; i++)
// {
// *eb = 0x00;
// eb += 1;
// }
// db = auxDb;
// eb = auxEb;
// uint32_t dbcounter = 0;
// uint32_t ebcounter = 0;
/* Regenerate db block and eb block. */
for (int64_t i = 0; i < ctrllen/24; i++)
{
/* Copy to the newFileBlock structure the reordered data to be modified and
* the extra data aswell.
*/
if (newFileBlock[i].dataBlock != NULL)
{
memcpy(db, newFileBlock[i].dataBlock, sizeof(uint8_t) * newFileBlock[i].ctrl[0]);
db += newFileBlock[i].ctrl[0];
}
if (newFileBlock[i].extraBlock != NULL)
{
memcpy(eb, newFileBlock[i].extraBlock, newFileBlock[i].ctrl[1]);
eb += newFileBlock[i].ctrl[1];
}
// dbcounter += newFileBlock[i].ctrl[0];
// ebcounter += newFileBlock[i].ctrl[1];
// printf("ctrl[0]: %ld\t ctrl[1]: %ld\t ctrl[2]: %ld\t y posicion de memoria \
// original: %ld\n", newFileBlock[i].ctrl[0], newFileBlock[i].ctrl[1]
// , newFileBlock[i].ctrl[2], newFileBlock[i].originalPos);
}
for(int64_t i = 0; i < ctrllen/24; i++)
{
if (newFileBlock[i].dataBlock != NULL)
{
free(newFileBlock[i].dataBlock);
}
if (newFileBlock[i].extraBlock != NULL)
{
free(newFileBlock[i].extraBlock);
}
}
free(newFileBlock);
free(problematicFields);
free(bytesNeededToSave);
auxDb = NULL;
auxEb = NULL;
}
int myFunctionToBeUsed(uint8_t* oldp, const int64_t oldsize, uint8_t* newp,
const int64_t newsize, uint8_t* patch, const int64_t patchsz)
{
int64_t dblen,eblen;
int64_t ctrllen;
uint8_t *db,*eb;
uint8_t *fileblock;
/* Here a lot of complex operations took place in order to calculate db, eb and fileblock. It has been extracted from bsdiff code so it is already tested. */
/* PREVIOS DATA HAS BEEN FILLED USING SOME COMPLEX FUNCTIONS TO CALCULATE DIFFERENCES BETWEEN 2 BINARIES. IF I DON'T CALL TO REORDERBLOCKS IT WORKS */
/*UNTIL HERE EVERYTHING SEEMS TO BE WORKING.*/
reorderBlocks(fileblock, db, eb, ctrllen, dblen, eblen, newsize);
/* The leak comes up as I free those and with a big file (1MB), with smaller ones it works well. */
free(db);
free(eb);
free(fileblock);
}
내가 같은 EB 및 DB 초기는 내부 해결 얻고 있음을 확인했다 함수를 사용하고 적절한 바이트 수를 메모리에 복사한다고 가정합니다 (원래 diff 프로그램은 순서가 변경되지 않고 작동합니다. 파일 블록 순서를 수정 한 것과 같은 방식으로 eb와 db를 재정렬합니다). memset db와 eb 중 하나를 사용할 수 없습니다. 순서를 바꾸지 않고 시도 했으므로 구조체에 복사 한 후 eb와 db로 다시 복사하고 memcmp를 사용하여 memcmp 결과가 0이 아닌 다른 결과를 얻는 방법을 비교했습니다. 수정 결과는 0이어야합니다.
내가 할 수있는 최선의 문제를 설명하려고 노력했다.
모든 조언이나 도움을 정말 환영합니다.
수정 0510/16 : 코드의 크기를 약간 줄였습니다. 내가 권고 한대로 valgrind을 사용하고 결과를 붙여 넣으려고합니다.
valgrind이 보고서를 제공하지만 어떻게 문제를 해결할 수 있는지 모르겠다. Valgrind의 설명서를 읽었습니다. 내가 GCC -static -g를 사용하는 경우 내가 무엇을 얻을이 *이 .c -o myprogram : 결과를 컴파일하는 걱정 동안
valgrind --track-origins=yes ./minibsdiff gen ivanTestBin/setup1.exe ivanTestBin/setup2.exe ivanTestBin/setuppatch
==5460== Memcheck, a memory error detector
==5460== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5460== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==5460== Command: ./minibsdiff gen ivanTestBin/setup1.exe ivanTestBin/setup2.exe ivanTestBin/setuppatch
==5460==
==5460== Conditional jump or move depends on uninitialised value(s)
==5460== at 0x4167F8: _int_free (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x460808: fillin_rpath (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x460E04: _dl_init_paths (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43C0E3: _dl_non_dynamic_init (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43C9B7: __libc_init_first (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x4059E4: (below main) (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== Uninitialised value was created
==5460== at 0x45DF09: brk (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43A1D8: sbrk (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x406106: __libc_setup_tls (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x40599C: (below main) (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460==
==5460== Conditional jump or move depends on uninitialised value(s)
==5460== at 0x41684D: _int_free (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x460808: fillin_rpath (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x460E04: _dl_init_paths (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43C0E3: _dl_non_dynamic_init (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43C9B7: __libc_init_first (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x4059E4: (below main) (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== Uninitialised value was created
==5460== at 0x45DF09: brk (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43A1D8: sbrk (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x406106: __libc_setup_tls (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x40599C: (below main) (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460==
==5460== Conditional jump or move depends on uninitialised value(s)
==5460== at 0x416248: malloc_consolidate (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x417D36: _int_malloc (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x419D20: malloc (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x45884F: _IO_file_doallocate (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x413A93: _IO_doallocbuf (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x412C97: _IO_file_overflow (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x4120A3: _IO_file_xsputn (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x44AA63: vfprintf (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x40C445: printf (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x4054C3: diff (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x4057CA: main (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== Uninitialised value was created
==5460== at 0x45DF09: brk (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x43A1D8: sbrk (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x406106: __libc_setup_tls (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460== by 0x40599C: (below main) (in /home/ivan/ota/binary_diff_tools/bsdiff-master/minibsdiff-master/minibsdiff)
==5460==
Generating binary patch between ivanTestBin/setup1.exe and ivanTestBin/setup2.exe
Old file = 967168 bytes
New file = 965632 bytes
Computing binary delta...
sizeof(delta('ivanTestBin/setup1.exe', 'ivanTestBin/setup2.exe')) = 39922 bytes
Successfully created patch; patch file name: ivanTestBin/setuppatch
==5460==
==5460== HEAP SUMMARY:
==5460== in use at exit: 0 bytes in 0 blocks
==5460== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5460==
==5460== All heap blocks were freed -- no leaks are possible
==5460==
==5460== For counts of detected and suppressed errors, rerun with: -v
==5460== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
것은 내가 정적 사용하지 않는 경우 :
수정 06/10/16 :
글쎄,이 문제를 해결했습니다. 문제는 db 및 eb에 올바른 양을 추가하지 않고 db 및 new에 newFileBlock의 내용을로드 한 경우입니다. 내 말은, 나는 ctrl [0]과 ctrl 1을 사용했고 newFileBlock [i] .ctrl [0]과 newFileBlock [i] .ctrl 1을 사용해야한다. 붙여 넣은 코드에서 이미 수정했습니다.
안부,
F.
memset (구조, 0, sizeof (구조));은'memset (구조, 0, sizeof (* 구조) * 크기);'이어야합니다. – mch
['valgrind'] (http://valgrind.org/)를 사용할 수 있습니까? 그렇다면 그렇게하십시오. 그렇지 않은 경우 코드를 MCVE ([MCVE])로 줄일 수 있습니까?일부 기능을 제거하십시오. 구조를 단순화한다. 충돌을 일으키는 데이터를 보여주십시오. –
@mch 그건 의견이 아니에요. 답변으로 제출해야합니다. – Sinkingpoint