I disassembled a 7,838,304-Byte portion of /usr/lib/x86_64-linux-gnu/dri/i965_dri.so using Capstone as shown below:
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#define MAX_DISAS_BYTES (0x8e0bb0 - 0x167150)
#define MAX_PATH_LEN 200
unsigned char code [MAX_DISAS_BYTES];
void disas()
{
cs_insn *insns;
int count;
unsigned long fileOff = 0x167150;
unsigned long addrOff = 0x167150;
unsigned int size = (0x8e0bb0 - 0x167150);
char fileName [MAX_PATH_LEN] = "/usr/lib/x86_64-linux-gnu/dri/i965_dri.so";
if (size > (MAX_DISAS_BYTES))
{
printf("fn size too large (%d > %d)\n", size , (MAX_DISAS_BYTES));
exit(1);
}
FILE *f = fopen(fileName, "rb");
if (!f)
{
printf("fopen");
exit(1);
}
if (fseek(f, fileOff, SEEK_SET) != 0)
{
printf("fseek");
fclose(f);
exit(1);
}
size_t n = fread(code, 1, MAX_DISAS_BYTES, f);
fclose(f);
csh handle;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
{
printf(stderr, "Failed to initialize Capstone\n");
exit(1);
}
// Enable detailed mode
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
count = cs_disasm(handle, code, size, addrOff, 0, &insns);
// bad mallocs
void *m1 = malloc(sizeof(cs_detail));
void *m2 = malloc(sizeof(cs_detail));
void *m3 = malloc(sizeof(cs_detail));
void *m4 = malloc(sizeof(cs_detail));
void *m5 = malloc(sizeof(cs_detail));
// end of bad mallocs
if (count > 0)
{
//for (size_t i = 0; i < count; i++)
//{
// printf("0x%"PRIx64":\t%s\t%s\n", insns[i].address, insns[i].mnemonic, insns[i].op_str);
//}
printf("to free\n");
sleep(5);
cs_free(insns, count);
printf("freed\n");
sleep(5);
}
else
{
printf("Failed to disassemble bytes at offset 0x%lx\n", fileOff);
exit(1);
}
cs_close(&handle);
}
int main()
{
disas();
return 0;
}
The problem is when I add the five malloc() calls marked as // bad mallocs, a huge portion of memory becomes unfreeable.
Precisely, before executing the program, on printf("to free\n"); and on printf("freed\n");, the system RSS is 2.8 GB, 6.28 GB and 5.86 GB, respectively.
Hence, almost 3 GB of memory is unfreeable. Note that, removing bad mallocs or freeing them before calling cs_free(), avoids this situation and cs_free() can release this extra memory. Why do five small dynamic allocations cause a huge amount of memory unfreeable? Any hint is appreciated.