Heap corruption with aligned memory allocator in tiny_cnn
Posted: Tue Mar 02, 2021 2:56 am
I have a tiny_cnn function parse_cifar10() for which I am tracing heap corruption.
I am including the file present at - [https://github.com/Xilinx/xilinx-tiny-c ... 0_parser.h]
ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
parse_cifar10(path, &test_images, &test_labels, -1.0, 1.0, 0, 0);
ESP_ERROR_CHECK( heap_trace_stop() );
heap_trace_dump();
Inside parse_cifar10() there is a vector img of type vec_t.
The vector type vec_t is a typedef defined as - "typedef std::vector<float_t, aligned_allocator<float_t, 64>> vec_t;" as shown below:
vec_t img(CIFAR10_IMAGE_SIZE);
printf("Heap check after img vector creation \n");
if(heap_caps_check_integrity_all(true)==false)
{
printf("Heap check failed after img vector creation \n");
}
printf("Size of image vector element %d and size of float %d\n", sizeof(vec_t), sizeof(float_t));
if (!ifs.read((char*) &buf[0], CIFAR10_IMAGE_SIZE)) break;
std::transform(buf.begin(), buf.end(), std::back_inserter(img),
[=](unsigned char c) { return scale_min + (scale_max - scale_min) * c / 255; });
train_images->push_back(img);
train_labels->push_back(label);
To compile with esp_idf, I defined flag ESP32 in make file.
I added the heap_caps_aligned_alloc() in file included from - "[https://github.com/Xilinx/xilinx-tiny-c ... llocator.h]" in function void* aligned_alloc(size_type align, size_type size) after _mm_malloc(size, align);
#elif defined(ESP32)
return heap_caps_aligned_alloc(align, size, MALLOC_CAP_SPIRAM);
To free the memory, in same file aligned_allocator.h in function void aligned_free(pointer ptr), I added
#elif defined(ESP32)
heap_caps_aligned_free(ptr);
The heap trace is as follows:
Start heap trace
Heap check after img vector creation
CORRUPT HEAP: Bad head at 0x3f85249c. Expected 0xabba1234 got 0x3fbffff4
Heap check failed after img vector creation
Size of image vector element 12 and size of float 4
2 allocations trace (100 entry buffer)
12 bytes (@ 0x3ffb7520) allocated CPU 0 ccount 0x3069e89c caller 0x401040a5:0x400d886c
0x401040a5: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
4 bytes (@ 0x3ffb753c) allocated CPU 0 ccount 0x30738b60 caller 0x401040a5:0x400da547
0x401040a5: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
16 bytes 'leaked' in trace (2 allocations)
total allocations 42 total frees 40
Calling heap_caps_check_integrity_all() after parse_cifar10() gives below output
CORRUPT HEAP: Bad head at 0x3f85b544. Expected 0xabba1234 got 0x3fbffff4
I think, the variable img is not freed when the scope of function parse_cifar10() ends.
I would highly appreciate any guidance in solving the Heap corruption.
Thank you!
I am including the file present at - [https://github.com/Xilinx/xilinx-tiny-c ... 0_parser.h]
ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
parse_cifar10(path, &test_images, &test_labels, -1.0, 1.0, 0, 0);
ESP_ERROR_CHECK( heap_trace_stop() );
heap_trace_dump();
Inside parse_cifar10() there is a vector img of type vec_t.
The vector type vec_t is a typedef defined as - "typedef std::vector<float_t, aligned_allocator<float_t, 64>> vec_t;" as shown below:
vec_t img(CIFAR10_IMAGE_SIZE);
printf("Heap check after img vector creation \n");
if(heap_caps_check_integrity_all(true)==false)
{
printf("Heap check failed after img vector creation \n");
}
printf("Size of image vector element %d and size of float %d\n", sizeof(vec_t), sizeof(float_t));
if (!ifs.read((char*) &buf[0], CIFAR10_IMAGE_SIZE)) break;
std::transform(buf.begin(), buf.end(), std::back_inserter(img),
[=](unsigned char c) { return scale_min + (scale_max - scale_min) * c / 255; });
train_images->push_back(img);
train_labels->push_back(label);
To compile with esp_idf, I defined flag ESP32 in make file.
I added the heap_caps_aligned_alloc() in file included from - "[https://github.com/Xilinx/xilinx-tiny-c ... llocator.h]" in function void* aligned_alloc(size_type align, size_type size) after _mm_malloc(size, align);
#elif defined(ESP32)
return heap_caps_aligned_alloc(align, size, MALLOC_CAP_SPIRAM);
To free the memory, in same file aligned_allocator.h in function void aligned_free(pointer ptr), I added
#elif defined(ESP32)
heap_caps_aligned_free(ptr);
The heap trace is as follows:
Start heap trace
Heap check after img vector creation
CORRUPT HEAP: Bad head at 0x3f85249c. Expected 0xabba1234 got 0x3fbffff4
Heap check failed after img vector creation
Size of image vector element 12 and size of float 4
2 allocations trace (100 entry buffer)
12 bytes (@ 0x3ffb7520) allocated CPU 0 ccount 0x3069e89c caller 0x401040a5:0x400d886c
0x401040a5: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
4 bytes (@ 0x3ffb753c) allocated CPU 0 ccount 0x30738b60 caller 0x401040a5:0x400da547
0x401040a5: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
16 bytes 'leaked' in trace (2 allocations)
total allocations 42 total frees 40
Calling heap_caps_check_integrity_all() after parse_cifar10() gives below output
CORRUPT HEAP: Bad head at 0x3f85b544. Expected 0xabba1234 got 0x3fbffff4
I think, the variable img is not freed when the scope of function parse_cifar10() ends.
I would highly appreciate any guidance in solving the Heap corruption.
Thank you!