Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Wednesday, May 23, 2007

C++ When is a function static variable initialized?

The following code is a rewrite of a singleton implementation presented on clc++ recently:
typedef unsigned int size_t;
class singleton{
public:
static singleton& create(){
static singleton * s = new singleton;
return *s;
}
static int shift(int x){
static int shift_by = 10;
x = shift_by + x;
shift_by = x;
return x;
}
private:
static void * operator new(size_t size){ }
singleton(){}
~singleton(){}
};

int main(){
singleton& s = singleton::create();
int x = 3;
singleton::shift(x);
}

The question was when singleton::create::s was initialized? I immediately thought this code was wrong because in a previous blog entry I have investigated how static variables are initialized inside a function. But at that time, I was investigating plain old data types (POD).

It turns out, as suggested, C++ has a more complicated scheme to initialize function static variables depending on the variable type, as in §6.7/4. Compiler is free to generate code to initialize the variable on the first possible entry to the function to initialize it. For POD and some types, compiler can, at compile time, initialize the variable on the .bss or .data segment. Let's see what's going on under the hood. Again we'll use the assembly output from g++ to investigate g++ behavior. Check out the symbol table portion of the assembly output of this c++ source file (g++ -s -c file.cpp):

.LFE11:
.size main, .-main
.weak _ZGVZN9singleton6createEvE1s
.section .bss._ZGVZN9singleton6createEvE1s,"awG",@nobits,_ZGVZN9singleton6createEvE1s,comdat
.align 8
.type _ZGVZN9singleton6createEvE1s, @object
.size _ZGVZN9singleton6createEvE1s, 8
_ZGVZN9singleton6createEvE1s:
.zero 8
.weak _ZZN9singleton6createEvE1s
.section .bss._ZZN9singleton6createEvE1s,"awG",@nobits,_ZZN9singleton6createEvE1s,comdat
.align 4
.type _ZZN9singleton6createEvE1s, @object
.size _ZZN9singleton6createEvE1s, 4
_ZZN9singleton6createEvE1s:
.zero 4
.weak _ZZN9singleton5shiftEiE8shift_by
.section .data._ZZN9singleton5shiftEiE8shift_by,"awG",@progbits,_ZZN9singleton5shiftEiE8shift_by,comdat
.align 4
.type _ZZN9singleton5shiftEiE8shift_by, @object
.size _ZZN9singleton5shiftEiE8shift_by, 4
_ZZN9singleton5shiftEiE8shift_by:
.long 10
.ident "GCC: (GNU) 4.1.1 20060525 (Red Hat 4.1.1-1)"
.section .note.GNU-stack,"",@progbits


The code for singleton::create:

_ZN9singleton6createEv:
.LFB2:
pushl %ebp
.LCFI6:
movl %esp, %ebp
.LCFI7:
pushl %ebx
.LCFI8:
subl $4, %esp
.LCFI9:
movl $_ZGVZN9singleton6createEvE1s, %eax
movzbl (%eax), %eax
testb %al, %al
jne .L8 <------------initialize on demand
movl $_ZGVZN9singleton6createEvE1s, (%esp)
call __cxa_guard_acquire
testl %eax, %eax
setne %al
testb %al, %al
je .L8
movl $1, (%esp)
call _ZN9singletonnwEj
movl %eax, %ebx
movl %ebx, (%esp)
call _ZN9singletonC1Ev
movl %ebx, _ZZN9singleton6createEvE1s
movl $_ZGVZN9singleton6createEvE1s, (%esp)
call __cxa_guard_release
.L8:
movl _ZZN9singleton6createEvE1s, %eax
addl $4, %esp
popl %ebx
popl %ebp
ret

assembly for singleton::shift:

_ZN9singleton5shiftEi:
.LFB3:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
movl _ZZN9singleton5shiftEiE8shift_by, %eax <--- already initialized, memory copy
addl %eax, 8(%ebp)
movl 8(%ebp), %eax
movl %eax, _ZZN9singleton5shiftEiE8shift_by
movl 8(%ebp), %eax
popl %ebp
ret

Thursday, May 17, 2007

Perl one liners: Part I

Sometimes Perl can be used in mysterious ways yet provides powerful facility to simplify code and
at the same time to improve its efficiency.

1. For example, the following code computes the current hour and minute of local time:

my @time = localtime(time);
my ($hour, $minute) = @time[2, 1];

To achive one liner, we can use the trick of Perl array copy construct. Array is copied by dereference the reference of original array:

my ($hour, $minute) = @{[localtime(time)]}[2, 1];

In both examples, a temporary array is created.

It's possible to avoid creating temporary array, but only one scalar variable can be retrieved:

my $hour = [localtime(time)]->[2];

2. Printing a 2 dimensional array

my @ar = ([1,2], [3,4], [5, 6]);

map { print join (', ', @$_); print "\n"; } @ar;

map is a particular powerful facility in Perl language. Beginners of Perl often found map code hard to understand and use. Do not be afraid. The essen of map is simply applying a code block or expression to every element of a list (usually an array or keys/values of a hash).

Wednesday, May 16, 2007

C++ Creating custom exception class

The following code segment demonstrates how to create a C++ custom exception class. The important thing to note is that the base exception:what() function has the following signature:
const char * what() const throw()

Thus to override the base exception::what function, the custom exception class must declare the function signature properly otherwise, it becomes a case of function name hidding as explained in one of the previous C++ articles.

class Exception : public exception
{
public:
Exception(string m="exception!") : msg(m) {}
~Exception() throw() {}
const char* what() const throw() { return msg.c_str(); }

private:
string msg;
};

int main()
{
try
{
throw Exception();
}
catch(exception& e)
{
cout << e.what() << endl;
}

return 0;
}

Tuesday, May 08, 2007

C++: Static class members awes

>> I read the following sentence from a c++ website, but can not
>> understand why. can anyone help me with it?
>>
>> "
>> An important detail to keep in mind when debugging or implementing a
>> program using a static class member is that you cannot initialize the
>> static class member inside of the class. In fact, if you decide to put
>> your code in a header file, you cannot even initialize the static
>> variable inside of the header file; do it in a .cpp file instead.
>>
>> "
>
> The Standard requires that every static data member is defined at the
> namespace level. In order to comply with the One Definition rule, you
> are more likely to succeed if you place the definition of the static
> data member in a .cpp file (instead of a header which can be included
> in more than one translation unit). Initialisation accompanies the
> definition. That's why you should initialise static data members in
> a .cpp file (and only in one .cpp file).

Initialization accompanies definition of a constant except in the case when a declaration of a static constant in a class supplies the initializer, in which case the definition (if any, and then outside the class) is sans initializer.

Example:

struct S
{
static int const x = 42; // Not a definition, per §9.4.2/2.
};

If the address of S::x is used, or in the standard's terminology, if S::x is "used", a definition is formally (but with current compilers not necessarily in practice) required, outside the class:

int const S::x; // A definition, per §9.4.2/4.

This construct is only supported for integral types and/including enum types.