valgrind complains about uninitialized bytes on C++ structure - c++

I have distilled by question down to a very simple example where I have a structure constructor that is initializing everything, yet valgrind complains about uninitialized bytes. The culprit seems to be the boolean member of the class, which causes padding bytes to be inserted before the size_t member. What is the right way to initialize those padding bytes so that valgrind doesn't complain?
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX 128
typedef struct foo_struct
{
foo_struct(const std::string& name, bool q = true) : q(q)
{
if (name.size() > MAX)
{
throw std::runtime_error("too big");
}
point_name_size = name.size();
memset(n, 0, sizeof(n));
memcpy(n, name.c_str(), name.size());
}
bool q;
size_t point_name_size;
char n[MAX];
} foo_t;
int main()
{
int fd = open("/tmp/foo", O_WRONLY | O_CREAT, 0666);
if (-1 == fd)
{
throw std::runtime_error("Can't create File Descriptor: " + std::string(strerror(errno)));
}
const foo_t f("hello");
ssize_t written = write(fd, &f, sizeof(f));
std::cout << "wrote " << written << std::endl;
return 0;
}
Compile and run with
g++ try.cpp && valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 ./a.out
The valgrind error is
==11790== Syscall param write(buf) points to uninitialised byte(s)
==11790== at 0x54ED154: write (write.c:27)
==11790== by 0x1093DE: main (in /home/gri6507/tmp/a.out)
==11790== Address 0x1fff000251 is on thread 1's stack
==11790== in frame #1, created by main (???:)

The right way to serialize a data structure into a chunk of bytes to be written to mass storage is to write a serializer that encodes the data into the desired format. Relying on things not specified by the standard (such as the endianness or type sizes) is simply wrong.
There are plenty of serialization libraries available.

What is the right way to initialize those padding bytes so that valgrind doesn't complain?
I'm not sure about 'the right way' to do this, but there are several possibilities.
you create members for the padding and initialize them
struct bar
{
size_t point_name_size;
char n[MAX];
bool q;
bool unused[7] ={};
};
This 'typically' has the same size as your struct on a 64 bit system. See here.
you fill yourself with 0's if you are trivially copyable
struct bar
{
bar()
{
static_assert(std::is_trivially_copyable_v<bar>);
memset(this, 0, sizeof(bar));
}
size_t point_name_size;
char n[MAX];
bool q;
};

Related

How to reliably get a destructor to overwrite buffer without it being optimized out in c++

I'm reviewing someone else's code and I See the in a destructor he is overwriting a buffer that is an int array inside the class. I thought maybe the compiler might optimize that out.
So I made a small program to test, and it does optimize the destructor out.
The only simple solution to this I found is to use attribute((optimize("O0"))) on the destructor. But there has to be a way to do this without using gcc-specific attributes.
Things I tried:
Setting the buffer to be volatile -- this works if you directly set the buffer in a for loop (not a memset or the like). But I really don't want this to be volatile, since it's not.
attribute((optimize("O0"))) works but is not portable, and is kinda ugly.
making my own new/delete with it's own memory pool. I was thinking if the compiler doesn't know how the memory is being used, it shouldn't optimize writes to it. The fact that this didn't work seems like a bug.
Setting up a class whose only job is to overwrite the buffer in the other memory. This works but man is it needlessly ugly.
I'm thinking a lot of application would want to do something like this. Not just zeroing out keys. Surely someone has run into this issue before, or I'm just doing something wrong.
Ideas?
g++ memset.cpp -O1 -fsanitize=undefined -Wall -Wextra
#include <stdio.h>
#include <string.h>
class example{
public:
int key[100];
~example(){
printf("destructor\n");
memset(key,0, sizeof(key));
}
};
void print_memory(int *in){
printf ("\n");
for(int i =0; i < 10; i++){
printf(" %2d:a: %08x ",i, in[i]);
}
}
int main(){
example *ptr;
{
example *it = new example;
ptr = it;
// fill memory with something.
for(int i = 0; i< 100; i++){
it->key[i] = rand();
}
printf("Done randomizing.\n");
print_memory(it->key);
delete it;
}
printf("\ndeleted\n");
print_memory(ptr->key);
printf("\n");
}
Output:
Done randomizing.
0:a: 6b8b4567 1:a: 327b23c6 2:a: 643c9869 3:a: 66334873 4:a: 74b0dc51 5:a: 19495cff 6:a: 2ae8944a 7:a: 625558ec 8:a: 238e1f29 9:a: 46e87ccd destructor
deleted
0:a: 00000000 1:a: 00000000 2:a: 0e57f010 3:a: 0000555b 4:a: 74b0dc51 5:a: 19495cff 6:a: 2ae8944a 7:a: 625558ec 8:a: 238e1f29 9:a: 46e87ccd
A bare metal way is to access it via volatile - that way it will not be optimized. A C way would be:
#include <cstddef>
void volatile_memset(volatile void *s, int c, size_t n) {
volatile unsigned char *m = reinterpret_cast<volatile unsigned char *>(s);
while (n--) {
*m++ = c;
}
}
int main() {
char key[200];
volatile_memset(key, 0, sizeof(key));
}
but I think in C++ you can:
#include <algorithm>
int main() {
char key[200];
std::fill_n<volatile char *>(key, sizeof(key)/sizeof(*key), 0);
}
or:
#include <algorithm>
#include <array>
int main() {
char key[200];
std::fill<volatile char *>(std::begin(key), std::end(key), 0);
}

c++ passing arrays in constructor without defining them elsewhere

I currently have this code:
#include "stdafx.h"
#include "AddressInfo.h"
AddressInfo::AddressInfo(int ammoCount, int pointerLevel, DWORD baseAddress, DWORD* offsetArray) {
ammo = ammoCount;
numPointers = pointerLevel;
this->baseAddress = baseAddress;
offsets = (DWORD*)malloc(sizeof(offsetArray));
this->offsets = offsetArray;
};
AddressInfo::~AddressInfo() {
delete[] offsets;
}
void AddressInfo::print() {
std::cout << this->offsets[0]<< std::endl;
}
DWORD x[] = { 0x374, 0x14, 0x0 };
AddressInfo* ammo = new AddressInfo(1000, 3, (DWORD)(0x00509B74), x);
int main()
{
ammo->print();
system("pause");
}
This code works, but I want to do the following:
Instead of pre-defining the array and passing it into the constructor, I want to pass the array in as follows: {0x374,0x14,0x0}
Is this possible / is this practical
I tried typecasting: (DWORD*) {0x374,0x14,0x0}
You should use std::vector for this task and for future tasks. Look how easy and clean it makes everything
#include <iostream>
#include <vector>
class AddressInfo
{
int ammoCount;
int pointerLevel;
std::vector<uint32_t> offsets;
public:
AddressInfo(int ammoCount, int pointerLevel, std::vector<uint32_t> offsets) :
ammoCount{ ammoCount }, pointerLevel{ pointerLevel }, offsets{ offsets }
{
}
void print(size_t i)
{
std::cout << this->offsets.at(i) << std::endl;
}
};
int main()
{
AddressInfo ammo (1000, 0x00509B74, { 0x374, 0x14, 0x0 });
ammo.print(0);
ammo.print(1);
ammo.print(2);
return 0;
}
https://ideone.com/WaLiP8
This constructor is just wrong
AddressInfo::AddressInfo(
int ammoCount,
int pointerLevel,
DWORD baseAddress,
DWORD* offsetArray)
{
ammo = ammoCount;
numPointers = pointerLevel;
this->baseAddress = baseAddress;
offsets = (DWORD*)malloc(sizeof(offsetArray));
this->offsets = offsetArray;
};
first you allocate using malloc, in C++ we usually use new since malloc does not call any constructors. second sizeof doesn't give the size of the array, it gives you the size of the pointer - it is the same as writing sizeof(DWORD*)
then after you allocated something for offsets to point to, you then let it point to the parameter so what bytes you allocated with malloc are leaked.
In your destructor you assume that offsetArray has previously been allocated with new[] and passed to the constructor but how will a user of your class know that?
Imagine somebody creating your AddressInfo using an array allocated on the stack.
DWORD myArray[10];
AddressInfo adr = new AddressInfo(ammoCount,pointerLevel,baseAddress,offsetArray);
People do not want to look into the implementation to look for assumptions, that is the whole idea of putting stuff in a class, to hide the implementation.
Instead use std::array or std::vector when you work with arrays in C++, you then create a much more transparent and clean design - see Kilzone Kids answer.

std::fstream crashes after main while using pre-allocated memory

I currently have a std::ofstream being created on the stack, and when it allocates off a global operator new that assigns it memory from a pre-allocated buffer the program will crash after main completes citing std::locale0 : line 59. Read Access Violation. nodeptr was 0x... as the program crash point. nodeptr's memory address is a real address. I have no idea why this is happening, and I can only assume it was because I misunderstand what the allocations are actually doing.
This behaviour happens on a release build tested on MSVC Version 19.10.25019 x86, building on debug has the program complete without a crash. Dr. Memory reports no leaks in debug mode.
Minimal Code:
#include <fstream>
#include <cstdlib>
std::uint8_t *byte = static_cast<std::uint8_t*>(malloc(134217728)); // 134217728 = 128 MiB
void *operator new(size_t bytes) throw(std::bad_alloc)
{
return static_cast<void*>(byte); // Tested empirically, and this is only called once so this shouldnt be a cause of a problem
}
void operator delete(void *memory) throw()
{}
int main()
{
std::ofstream out("abc");
free(byte);
}
There are two obvious bugs:
What if operator new is called more than once? What if the constructor of out constructs a sub-object?
You free byte while out is still in scope. When out's destructor runs, you've already returned its memory to the system.
Try this:
#include <fstream>
#include <cstdlib>
std::uint8_t *byte = static_cast<std::uint8_t*>(malloc(134217728)); // 134217728 = 128 MiB
void *operator new(size_t bytes) throw(std::bad_alloc)
{
static int offset = 0;
void * ret = static_cast<void*>(byte + offset);
offset += 16 * ((bytes + 15) / 16);
return ret;
}
void operator delete(void *memory) throw()
{}
int main()
{
{
std::ofstream out("abc");
}
free(byte);
}
It appears as it is a Visual Studio bug regarding custom allocations and std::locale.

Valgrind detects memory leak at fclose()

Why does valgrind say I've got memory leak at the fclose() call?
#include <stdio.h>
class Stream
{
public:
Stream();
~Stream();
private:
char* pszOutput;
size_t size;
FILE* file;
};
Stream::Stream()
{
file = open_memstream(&pszOutput, &size);
}
Stream::~Stream()
{
fclose(file);
}
int main()
{
Stream s;
return 0;
}
Valgrind report:
==52387== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==52387== at 0x4C28CCE: realloc (vg_replace_malloc.c:632)
==52387== by 0x5639CA3: _IO_mem_finish (memstream.c:132)
==52387== by 0x5635956: fclose##GLIBC_2.2.5 (iofclose.c:66)
Does it matter to initialize pszOutput or size? Or maybe I need to add something else?
From : http://linux.die.net/man/3/open_memstream
The open_memstream() function opens a stream for writing to a buffer. The buffer is dynamically allocated (as with malloc(3)), and automatically grows as required. After closing the stream, the caller should free(3) this buffer.
So according to this you need to free(pszOutput) after your file descriptor is closed.

Direct execution of the data

What is the best approach to make my program to execute the data. Say, I wrote the (so-called) compiler for x86_64 machine:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstdint>
struct compiler
{
void op() const { return; }
template< typename ...ARGS >
void op(std::uint8_t const _opcode, ARGS && ..._tail)
{
code_.push_back(_opcode);
return op(std::forward< ARGS >(_tail)...);
}
void clear() { code_.clear(); }
long double operator () () const
{
// ?
}
private :
std::vector< std::uint8_t > code_;
};
int main()
{
compiler compiler_; // long double (*)();
compiler_.op(0xD9, 0xEE); // FLDZ
compiler_.op(0xC3); // ret
std::cout << compiler_() << std::endl;
return EXIT_SUCCESS;
}
But I don't know how to implement operator () correctly. I suspect, that I must put all the contents of code_ into contiguous memory chunk and then cast to long double (*)(); and call this. But there is some difficulties:
Should I use VirtualProtect(Ex) (+ FlushInstructionCache) on Windows? And something similar on Linux?
What is the container, that reliably places the bytes in the memory in proper manner (i.e. one by one)? And also allows to get the pointer to memory chunk.
First, you will need to allocate the code as executable [using VirtualAlloc with "executable" flag in Windows, and mmap using "MAP_EXECUTABLE" as one of the flags]. It's probably a lot easier to allocate a large region of this kind of memory, and then have a "allocation function" for your content. You could possibly use virtualprotect and whatever the corresponding function is in Linux, but I'd say that allocating as executable in the first place is a better choice. I don't believe you need to flush instruction cache it the memory is already allocated as executable - certainly not on x86 at least - and since your instructions are x86 instructions, I guess that's a fair limitation.
Second, you'll need to make something like a function pointer to your code. SOmething like this should do it:
typedef void (*funcptr)(void);
funcptr f = reinterpret_cast<funcptr>(&code_[0]);
should do the trick.