2016-10-04 22 views
1

私はいつかこの問題に苦しんでいると私はこのリークが起こっている理由を見つけることができません。ダブルフリーまたは破損(!prev)と私はなぜCでの理由を理解することができません

私がふりをするのは、ファイルブロックを注文するときにebとdbを注文することです。最初に、その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初期は内部で対処取得していますことを確認しています私はメモリに適切なバイト数をコピーします(元のdiffprogramは並べ替えられず、動作しますが、私はファイルブロックの順序を変更したのと同じ方法でebとdbを並べ替えます)。私はmemset dbとebのいずれもできません、私は並べ替えなしでこれを試したので、構造体にコピーし、再度ebとdbにコピーしました。変更結果はゼロになるはずです。

私は自分の問題を私ができる限り説明しようとしました。

アドバイスや援助は本当に歓迎されます。

EDITED 05/10/16: コードのサイズを少し小さくしました。私がアドバイスされたので、私はとvalgrindを使用して結果を貼り付けます。

valgrind私にはこの報告書がありますが、どのように問題を解決できるか分かりません。私はValgrindのドキュメントを読んでいます。

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) 

結果をコンパイルすることは心配である一方で、私は、静的な使用しない場合:私はgccの-static -gを使用している場合、私は.C -o MYPROGRAM *何を得るこの

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]を使う必要があります。私はすでに貼り付けられたコードでそれを修正しました。

よろしくお願いいたします。

関連する問題