"Guess what the bug is" game..

Started by
33 comments, last by Dmytry 19 years, 6 months ago
A bit of context first: i recently discovered a crash bug when writing in a professional application a piece of code to log some strings into a byte buffer (in order to easily dump it to disk later). I'm not going to say what the bug is (it's part of the game!), nor on which O.S./system it happens, but i replicated it here in a simple example program:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// and all your usual includes - that's not the point here

char *log_buffer = NULL;
int log_offset = 0;

// Function in which the crash happens:
void log_string(char *txt)
{
	const int len = strlen(txt);
	*((int *)(log_buffer + log_offset)) = len;
	log_offset += sizeof(int);
	memcpy(log_buffer + log_offset, txt, len);
	log_offset += len;
}

int main(int argc, char *argv[])
{
        // allocate enough room for our test:
	log_buffer = new char[4096];
	log_offset = 0;

	log_string("This is a simple log string");
	log_string("But this call is going to crash");

        // we'll never reach that anyway but:
        delete [] log_buffer;

	return 0;
}
Will you be able to spot the problem ? Y.
Advertisement
Hmm... spider senses point to the line:
*((int *)(log_buffer + log_offset)) = len;
although the only thing wrong with it that I can see is that you might be copying an int to a non-dword-aligned block of memory.

Is it cheating to run it and see? :)

[edit: Can you initialize a const int with a calculated value like that? ]
The "const int" ?
It functions properly for me!
hmm,
The const int thing shouldnt be a problem.
Maybe its because you didnt explicitely null-terminate the strings(strlen takes a null-terminated string).
Causing the memory to be full on the second call.

-CProgrammer
Quote:Maybe it's because you didnt explicitely null-terminate the strings(strlen takes a null-terminated string).


That should be fine. strlen() operates on the argument txt, which in this case is a string literal. So it should be null-terminated.

I also ran the code with no problem. I stepped through it and everything worked as expected. As fractoid suggested, could it have anything to do with memory alignment?
He's given us a clue by explicitly telling us that he's not telling us what OS/system - maybe it's something to do with word size? (16 vs 32 bit integers?)
Well, strlen() returns unsigned int, but he uses int for the variables. I don't know in which OS this could be a problem though.
Quote:Original post by fractoid
Hmm... spider senses point to the line:
*((int *)(log_buffer + log_offset)) = len;
although the only thing wrong with it that I can see is that you might be copying an int to a non-dword-aligned block of memory.


Yep, I agree, on various CPUs like the 68000 you'll get an address exception for that because the write is on an odd address. The BCPL style string brings it all back ;o)

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

I'm pretty sure that all compilers will align newly allocated memory on 32 or 64 bit boundaries to avoid weird problems like that. Even if they didn't, there's no reason why it wouldn't work: memory is byte addressable.

This topic is closed to new replies.

Advertisement