Debugging another memory bug.
This commit is contained in:
parent
85ff28360b
commit
8122ca265d
43
Arena.cc
43
Arena.cc
|
@ -13,6 +13,7 @@
|
|||
|
||||
#define PROT_RW (PROT_WRITE|PROT_READ)
|
||||
#elif defined(__WIN64__) || defined(__WIN32__)
|
||||
#include <Windows.h>
|
||||
#include <fileapi.h>
|
||||
#endif
|
||||
|
||||
|
@ -144,7 +145,47 @@ Arena::Create(const char *path, size_t fileSize, mode_t mode)
|
|||
int
|
||||
Arena::Open(const char *path)
|
||||
{
|
||||
HANDLE fHandle;
|
||||
size_t fSize;
|
||||
size_t fRead = 0;
|
||||
size_t fRemaining;
|
||||
auto cursor = this->store;
|
||||
OVERLAPPED overlap;
|
||||
|
||||
fHandle = CreateFileA(
|
||||
(LPSTR)path,
|
||||
GENERIC_READ,
|
||||
(FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE),
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (fHandle == INVALID_HANDLE_VALUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!GetFileSizeEx(fHandle, reinterpret_cast<PLARGE_INTEGER>(&fSize))) {
|
||||
CloseHandle(fHandle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->SetAlloc(fSize);
|
||||
|
||||
fRemaining = fSize;
|
||||
while (fRemaining != 0) {
|
||||
overlap.Offset = (fSize - fRemaining);
|
||||
if (!ReadFile(fHandle, cursor, fSize, reinterpret_cast<LPDWORD>(&fRead), &overlap)) {
|
||||
CloseHandle(fHandle);
|
||||
this->Destroy();
|
||||
return -1;
|
||||
}
|
||||
|
||||
cursor += fRead;
|
||||
fRemaining -= fRead;
|
||||
}
|
||||
|
||||
CloseHandle(fHandle);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -227,7 +268,7 @@ operator<<(std::ostream &os, Arena &arena)
|
|||
{
|
||||
auto cursor = arena.Store();
|
||||
char cursorString[33] = {0};
|
||||
snprintf(cursorString, 32, "%#016lx", cursor);
|
||||
snprintf(cursorString, 32, "%#016llx", cursor);
|
||||
|
||||
os << "Arena<";
|
||||
switch (arena.Type()) {
|
||||
|
|
8
Arena.h
8
Arena.h
|
@ -1,3 +1,9 @@
|
|||
/// @file Arena.h
|
||||
/// @author K. Isom
|
||||
/// @brief Memory management using an arena.
|
||||
/// @section DESCRIPTION
|
||||
/// Arena defines a memory management backend for pre-allocating memory.
|
||||
|
||||
#ifndef KIMODEM_ARENA_H
|
||||
#define KIMODEM_ARENA_H
|
||||
|
||||
|
@ -41,6 +47,8 @@ public:
|
|||
int MemoryMap(int memFileDes, size_t memSize); // Arena will own fd.
|
||||
int Create(const char *path, size_t fileSize, mode_t mode);
|
||||
int Open(const char *path);
|
||||
#elif defined(__WIN64__) || defined(__WIN32__)
|
||||
int Open(const char *path);
|
||||
#endif
|
||||
|
||||
uint8_t *NewCursor() const { return this->store; }
|
||||
|
|
52
Buffer.cc
52
Buffer.cc
|
@ -4,8 +4,11 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include "Buffer.h"
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "Buffer.h"
|
||||
|
||||
namespace klib {
|
||||
|
||||
|
@ -140,7 +143,7 @@ void
|
|||
Buffer::Resize(size_t newCapacity)
|
||||
{
|
||||
if (newCapacity < this->length) {
|
||||
return;
|
||||
newCapacity = nearestPower(this->length + newCapacity);
|
||||
}
|
||||
|
||||
auto newContents = new uint8_t[newCapacity];
|
||||
|
@ -151,6 +154,7 @@ Buffer::Resize(size_t newCapacity)
|
|||
}
|
||||
|
||||
delete this->contents;
|
||||
this->contents = nullptr;
|
||||
this->contents = newContents;
|
||||
this->capacity = newCapacity;
|
||||
}
|
||||
|
@ -183,15 +187,23 @@ Buffer::Clear()
|
|||
void
|
||||
Buffer::Reclaim()
|
||||
{
|
||||
std::cout << "clear" << std::endl;
|
||||
this->Clear();
|
||||
|
||||
std::cout << "nullptr check" << std::endl;
|
||||
if (this->contents == nullptr) {
|
||||
std::cout << "assert checks" << std::endl;
|
||||
assert(this->length == 0);
|
||||
assert(this->capacity == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "delete " << this->Capacity() << "B" << std::endl;
|
||||
this->HexDump(std::cout);
|
||||
delete this->contents;
|
||||
std::cout << "reset contents" << std::endl;
|
||||
this->contents = nullptr;
|
||||
std::cout << "reset capacity" << std::endl;
|
||||
this->capacity = 0;
|
||||
}
|
||||
|
||||
|
@ -207,6 +219,42 @@ Buffer::mustGrow(size_t delta) const
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Buffer::HexDump(std::ostream &os)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
size_t index = 0;
|
||||
|
||||
os << std::hex;
|
||||
os << std::setfill('0');
|
||||
|
||||
for (index = 0; index < this->length; index++) {
|
||||
bool eol = (index % 16) == 0;
|
||||
if (eol && (index > 0)) {
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
if (eol) {
|
||||
os << std::setw(8);
|
||||
os << index << " ";
|
||||
os << std::setw(2);
|
||||
}
|
||||
|
||||
os << (unsigned short)this->contents[index];
|
||||
|
||||
if ((index % 15) != 0 || (index == 0)) {
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
|
||||
if ((index % 16) != 0) {
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
os << std::setw(0) << std::dec;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
Buffer::shiftRight(size_t offset, size_t delta)
|
||||
{
|
||||
|
|
3
Buffer.h
3
Buffer.h
|
@ -5,6 +5,7 @@
|
|||
#ifndef KGE_BUFFER_H
|
||||
#define KGE_BUFFER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
|
@ -39,6 +40,8 @@ public:
|
|||
void Clear();
|
||||
void Reclaim();
|
||||
|
||||
void HexDump(std::ostream &os);
|
||||
|
||||
uint8_t &operator[](size_t index);
|
||||
private:
|
||||
size_t mustGrow(size_t delta) const;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# Doxygen support for klib.
|
||||
find_package(Doxygen)
|
||||
|
||||
if (${DOXYGEN_FOUND})
|
||||
|
||||
doxygen_add_docs(klib_docs
|
||||
${HEADER_FILES} ${SOURCE_FILES}
|
||||
USE_STAMP_FILE)
|
||||
|
||||
endif ()
|
|
@ -19,13 +19,22 @@ set(HEADER_FILES
|
|||
Arena.h
|
||||
Buffer.h
|
||||
Dictionary.h
|
||||
Test.h
|
||||
TLV.h)
|
||||
|
||||
set(SOURCE_FILES
|
||||
Arena.cc
|
||||
Buffer.cc
|
||||
Dictionary.cc
|
||||
Test.cc
|
||||
TLV.cc)
|
||||
|
||||
add_library(klib STATIC
|
||||
Arena.cc
|
||||
Buffer.cc
|
||||
Dictionary.cc
|
||||
TLV.cc)
|
||||
TLV.cc
|
||||
)
|
||||
install(TARGETS klib LIBRARY DESTINATION ${PREFIX}/lib)
|
||||
install(FILES ${HEADER_FILES} DESTINATION include/klib)
|
||||
install(FILES klibConfig.cmake DESTINATION share/klib/cmake)
|
||||
|
@ -45,11 +54,12 @@ add_executable(buffer_test bufferTest.cc)
|
|||
target_link_libraries(buffer_test klib)
|
||||
add_test(bufferTest buffer_test)
|
||||
|
||||
include(CMakePack.txt)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
klibConfig.cmake
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
include(CMakePack.txt)
|
||||
include(CMakeDocs.txt)
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Created by kyle on 2023-10-09.
|
||||
//
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace klib {
|
||||
|
||||
|
||||
void
|
||||
TestAssert(bool condition, std::string message = "Assertion failed.")
|
||||
{
|
||||
#if defined(NDEBUG)
|
||||
if (!condition) {
|
||||
throw AssertionFailed(message);
|
||||
}
|
||||
#else
|
||||
if (!condition) {
|
||||
std::cerr << message << std::endl;
|
||||
}
|
||||
assert(condition);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
AssertionFailed::AssertionFailed(std::string message) : msg(message)
|
||||
{
|
||||
}
|
||||
|
||||
char *
|
||||
AssertionFailed::what() const noexcept
|
||||
{
|
||||
return const_cast<char *>(this->msg.c_str());
|
||||
}
|
||||
|
||||
|
||||
} // namespace klib
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// Created by kyle on 2023-10-09.
|
||||
//
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef KLIB_TEST_H
|
||||
#define KLIB_TEST_H
|
||||
|
||||
|
||||
namespace klib {
|
||||
|
||||
|
||||
void
|
||||
TestAssert(bool condition, std::string message);
|
||||
|
||||
|
||||
class AssertionFailed : public std::exception {
|
||||
public:
|
||||
explicit AssertionFailed(std::string message);
|
||||
|
||||
char *what() const noexcept override;
|
||||
|
||||
public:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
|
||||
} // namespace klib
|
||||
|
||||
#endif //KLIB_TEST_H
|
|
@ -18,12 +18,26 @@ main(int argc, char *argv[])
|
|||
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
|
||||
std::cout << "remove end" << std::endl;
|
||||
buffer.Remove(buffer.Length() - 1);
|
||||
buffer.Remove(0, 5);
|
||||
buffer.Insert(0, 'g');
|
||||
buffer.Insert(1, (uint8_t *) "oodbye", 6);
|
||||
|
||||
std::cout << "remove start" << std::endl;
|
||||
buffer.Remove(0, 5);
|
||||
|
||||
std::cout << "insert char" << std::endl;
|
||||
buffer.Insert(0, 'g');
|
||||
|
||||
std::cout << "insert chunk" << std::endl;
|
||||
buffer.Insert(1, (uint8_t *) "oodbye", 6);
|
||||
std::cout << "cruel" << std::endl;
|
||||
buffer.Insert(9, (uint8_t *)"cruel ", 6);
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
buffer.HexDump(std::cout);
|
||||
|
||||
std::cout << "reclaim" << std::endl;
|
||||
buffer.Reclaim();
|
||||
|
||||
std::cout << "append" << std::endl;
|
||||
buffer.Append("and now for something completely different...");
|
||||
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
|
|
|
@ -48,7 +48,7 @@ main(int argc, const char *argv[])
|
|||
abort();
|
||||
}
|
||||
#else
|
||||
if (AllocNewArena(arena, ARENA_SIZE) == -1) {
|
||||
if (arena.SetAlloc(ARENA_SIZE) == -1) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "Arena.h"
|
||||
#include "Test.h"
|
||||
#include "TLV.h"
|
||||
|
||||
#include "testFixtures.h"
|
||||
|
||||
using namespace klib;
|
||||
|
||||
|
||||
static uint8_t arenaBuffer[ARENA_SIZE];
|
||||
|
||||
|
|
Loading…
Reference in New Issue