2016-10-04 4 views
1

Я когда-то боролся с этой проблемой, и я не могу найти причину, по которой происходит эта утечка.двойная свобода или коррупция (! Prev), и я не могу понять, почему в C

Что я делаю вид, это заказать eb и db, когда я заказываю файловый блок, поэтому сначала я заказываю файловый блок с его элементами памяти eb и db. После этого я хочу скопировать эти данные, хранящиеся в структуре, в 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); 
} 

Я проверил, что я получаю то же самое еи и дб первоначальный адрес внутри и я копирую в память соответствующее количество байтов (исходная diffprogram не переупорядочивает и работает, я просто переупорядочиваю eb и db так же, как я изменил порядок файлового блока). Я не могу либо memset db и eb, я пробовал это без переупорядочения, поэтому просто копировал в структуру и снова в eb и db, и я использовал memcmp для сравнения результатов, получающих результаты memcmp differents до ZERO, и поскольку я не делал никаких изменение результата должно быть ZERO.

Я попытался объяснить свою проблему как можно лучше.

Любые советы или помощь будут действительно приветствоваться.

EDITED 05/10/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

EDITED 06/10/16:

Ну, я решил это. Проблема заключалась в том, что я не добавлял правильную сумму в адрес указателя db и eb, в котором я загрузил содержимое newFileBlock в db и eb снова. Я имею в виду, я использовал ctrl [0] и ctrl 1, и я должен использовать newFileBlock [i] .ctrl [0] и newFileBlock [i] .ctrl 1. Я уже исправил его в вставленном коде.

С наилучшими пожеланиями,

F.

+9

'memset (& structure, 0, sizeof (structure));' должен быть 'memset (структура, 0, sizeof (* structure) * size);'. – mch

+0

Можете ли вы использовать ['valgrind'] (http://valgrind.org/)? Если да, сделайте это. Если нет, можете ли вы уменьшить код до MCVE ([MCVE]).Устранить некоторые из функций; упростить структуры; покажите нам данные, которые приводят к сбою. –

+0

@mch Это не комментарий. Вы должны представить это как ответ. – Sinkingpoint

ответ

0

Ну, я решил это. Проблема заключалась в том, что я не добавлял правильную сумму в адрес указателя db и eb, в котором я загрузил содержимое newFileBlock в db и eb снова. Я имею в виду, я использовал ctrl [0] и ctrl1, и я должен использовать newFileBlock [i] .ctrl [0] и newFileBlock [i] .ctrl [1]. Я уже исправил его в вставленном коде.

С уважением.

 Смежные вопросы

  • Нет связанных вопросов^_^