2016-10-04 2 views
1

나는이 문제로 언젠가 고투하고 있으며,이 누출이 일어나는 이유를 찾을 수 없다.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) 

것은 내가 정적 사용하지 않는 경우 :

Valgrind

수정 06/10/16 :

글쎄,이 문제를 해결했습니다. 문제는 db 및 eb에 올바른 양을 추가하지 않고 db 및 new에 newFileBlock의 내용을로드 한 경우입니다. 내 말은, 나는 ctrl [0]과 ctrl 1을 사용했고 newFileBlock [i] .ctrl [0]과 newFileBlock [i] .ctrl 1을 사용해야한다. 붙여 넣은 코드에서 이미 수정했습니다.

안부,

F.

+9

memset (구조, 0, sizeof (구조));은'memset (구조, 0, sizeof (* 구조) * 크기);'이어야합니다. – mch

+0

['valgrind'] (http://valgrind.org/)를 사용할 수 있습니까? 그렇다면 그렇게하십시오. 그렇지 않은 경우 코드를 MCVE ([MCVE])로 줄일 수 있습니까?일부 기능을 제거하십시오. 구조를 단순화한다. 충돌을 일으키는 데이터를 보여주십시오. –

+0

@mch 그건 의견이 아니에요. 답변으로 제출해야합니다. – Sinkingpoint

답변

0

글쎄, 나는이 문제를 해결했다. 문제는 db 및 eb에 올바른 양을 추가하지 않고 db 및 new에 newFileBlock의 내용을로드 한 경우입니다. 나는 ctrl [0]과 ctrl1을 사용했고 newFileBlock [i] .ctrl [0]과 newFileBlock [i] .ctrl [1]을 사용해야합니다. 붙여 넣은 코드에서 이미 수정했습니다.

감사합니다.

관련 문제