Wednesday, September 29, 2010

delete null pointer


iso c++ 03
/2 ... if the value of the operand of delete is the null pointer the
operation has no effect.

/7   The delete-expression will call a deallocation function (

/2 ... the value of the operand of delete may be a null pointer value.

/7   If the value of the operand of the delete-expression is not a
null pointer value, the delete-expression will call a deallocation
function ( Otherwise, it is unspecified whether the
deallocation function will be called. [ Note: The deallocation
function is called regardless of whether the destructor for the
object or some element of the array throws an exception. -- end note ]

Wednesday, September 22, 2010

Benford's law

Interesting article in wikipedia.

Benford's law

Benford's law, also called the first-digit law, states that in lists of
numbers from many (but not all) real-life sources of data, the leading
digit is distributed in a specific, non-uniform way. According to this
law, the first digit is 1 almost one third  of the time, and larger
digits occur as the leading digit with lower and lower frequency, to the
point where 9 as a first digit occurs less than one time in twenty.

The distribution is as follows:
1     30.1%
2     17.6%
3     12.5%
4     9.7%
5     7.9%
6     6.7%
7     5.8%
8     5.1%
9     4.6%

Is it useful? Yep.
Following this idea, Mark Nigrini showed that Benford's law could be used
as an indicator of accounting and expenses fraud.

In the United States, evidence based on Benford's law is legally admissible
in criminal cases at the federal, state, and local levels.

So, whenever you're about to fake some data - use digits between 5 and 9
carefully. You've been warned.

Miklos Szeredi: memory barrier question

Miklos Szeredi posted a question about memory barriers (lkml).
Which lead to an interesting discussion on memory barriers, compilers
and the Universe.

Please read

Thursday, September 16, 2010

ext4 regression


Commit 66e61a9e9504f61b9a928c9055368c81da613a50 intorduced
ext4: Once a day, printk file system error information to dmesg

via kernel timer.

Error report may look like
[  313.485876] EXT4-fs (sda6): error count: 13
[  313.485887] EXT4-fs (sda6): initial error at 1283093815: ext4_lookup:1052: inode 4980737
[  313.485895] EXT4-fs (sda6): last error at 1283094174: ext4_lookup:1052: inode 4980737

and I find it quite useful.

Sad but true - calling print_daily_error_info (by timer event)
on umounted fs will cause NULL pointer derefernce on superblock inode
(EXT4_SB(sb) returns NULL) resulting in OOPS (fatal error during
soft IRQ).

Stack trace will look similar to this one:
(lots of helpfull info cut)


And the solution is:

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2614774..751997d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -719,6 +719,7 @@ static void ext4_put_super(struct super_block *sb)
             ext4_abort(sb, "Couldn't clean up the journal");

+    del_timer(&sbi->s_err_report);

Ted Ts'o wrote:
Good catch!  Thanks for the patch.  I will include this into ext4
tree, and I will probably push it separately to Linus so that it gets
into 2.6.36, since this is a regresssion.

I had some concerns about print_daily_error_info
> By the way, isn't print_daily_error_info racy? Is it safe to call
> print_daily_error_info
> (by timer event (softirq)) when we're remounting fs, etc.?

Ted Ts'o answered:
It should be fine.  Remounting doesn't actually change out the struct
superblock.  There is a chance that the information might not be fully
complete if an error is printed exactly as the same time as
print_daily_error_info() is run, but I'm not sure it's worth trying to
protect against that race, since the worst that this will mean is a
confusing report in the /var/log/messages file, and the ext4 error
message will be printed right next to it, which will have all of the
information the system administrator will need.


Wednesday, September 15, 2010

const iterators for elements removal

Q: Adam Badura

What is the point of const iterators being unusable for elements
        I mean that if I have a const collection object then no matter what
iterators I have I will not be able to erase any element. But if I
have a non-const collection object then why am I not allowed to erase
its elements with a const iterator? After all I could as well take new
non-const begin and advance it until it is equal to the const iterator
and use such iterator for erasure.

A: Bo Persson
You are right, this will be fixed in the next standard, C++0x. 

 A: Daniel Kr├╝gler
Perfectly right - therefore the Standard Library has fixed this
awful state by accepting LWG issue: lwg-defects
It is the constness of the container which should control whether it can be modified through a
member function such as erase(), not the constness of the iterators.

via comp.lang.c++.moderated.

Tuesday, September 14, 2010

"We no longer support gcc 3.x, so remove the workaround for it."

 H. Peter Anvin wrote:
We no longer support gcc 3.x, so remove the workaround for it.

[PATCH 1/5] Disallow building with gcc < 3.4
[PATCH 2/5] x86, gcc: Disallow building Linux/x86 with gcc 3.x/4.0 

[PATCH 3/5] x86, cpu: Remove gcc 3.x workarounds in
[PATCH 4/5] x86, mem: Remove gcc < 4.1 support code for memcpy()
[PATCH 5/5] x86, bitops: Remove gcc < 4.1 workaround

This patchset bumps the minimum supported gcc version to 3.4 for the
general kernel, and to 4.1 for x86.
Please read and 

Thursday, September 9, 2010

it's possible that there won't be any at all

Willy Tarreau wrote:
Some of you have noticed that the last update was released 7 months ago.
This is long, but these days, very few of the issues reported on 2.6 also
affect 2.4, so basically the number of bug reports on 2.4 fades out quite
So I'm releasing here. If nothing happens before September 2011,
it's possible that there won't be any at all. By that time, the
2.6 kernel will have been available for almost 8 years, this should have
been enough for anyone to have a look at it. Users now have one year to
migrate or to report critical bugs.
At one point, I envisaged to start a 2.4.38 with a bunch of updated drivers.
Now I'd prefer that the users migrate to 2.6. 

 Please read message.

Wednesday, September 1, 2010

The cost of static



suppose we have very simple and dumb code:
void save_state(int i) {
    static int _foo_i = i + 0x09;
    static int _foo_j = i;

g++ -O2 will give us:

   4005c0 <+0>:    cmpb   $0x0,0x200491(%rip)        # 0x600a58 <_ZGVZ10save_stateiE6_foo_i>
   4005c7 <+7>:    push   %rbx
   4005c8 <+8>:    mov    %edi,%ebx
   4005ca <+10>:    je     0x400600 <_Z10save_statei+64>
   4005cc <+12>:    cmpb   $0x0,0x20048d(%rip)        # 0x600a60 <_ZGVZ10save_stateiE6_foo_j>
   4005d3 <+19>:    je     0x4005e0 <_Z10save_statei+32>
   4005d5 <+21>:    pop    %rbx
   4005d6 <+22>:    retq  
   4005d7 <+23>:    nopw   0x0(%rax,%rax,1)
   4005e0 <+32>:    mov    $0x600a60,%edi
   4005e5 <+37>:    callq  0x4004a0 <__cxa_guard_acquire@plt>
   4005ea <+42>:    test   %eax,%eax
   4005ec <+44>:    je     0x4005d5 <_Z10save_statei+21>
   4005ee <+46>:    mov    %ebx,0x200474(%rip)        # 0x600a68 <_ZZ10save_stateiE6_foo_j>
   4005f4 <+52>:    mov    $0x600a60,%edi
   4005f9 <+57>:    pop    %rbx
   4005fa <+58>:    jmpq   0x4004c0 <__cxa_guard_release@plt>
   4005ff <+63>:    nop
   400600 <+64>:    mov    $0x600a58,%edi
   400605 <+69>:    callq  0x4004a0 <__cxa_guard_acquire@plt>
   40060a <+74>:    test   %eax,%eax
   40060c <+76>:    je     0x4005cc <_Z10save_statei+12>
   40060e <+78>:    lea    0x9(%rbx),%eax
   400611 <+81>:    mov    $0x600a58,%edi
   400616 <+86>:    mov    %eax,0x200450(%rip)        # 0x600a6c <_ZZ10save_stateiE6_foo_i>
   40061c <+92>:    callq  0x4004c0 <__cxa_guard_release@plt>
   400621 <+97>:    jmp    0x4005cc <_Z10save_statei+12>

First of all we're checking global _ZGVZ10save_stateiE6_foo_i to see whether local
_ZZ10save_stateiE6_foo_i has been initialized with default value (and by the way to
protect it).

After all those crazy do_lookup_x, _dl_name_match_p, check_match.10800, _dl_lookup_symbol_x, etc.
we have
0x00007ffff7b913a3 <+179>:    movb   $0x1,0x1(%rdi)
in __cxa_guard_acquire, which sets our global _ZGVZ10save_stateiE6_foo_i to:
0x600a58 <_ZGVZ10save_stateiE6_foo_i>:    0x00000100

   0x00007ffff7b91459 <+57>:    movb   $0x0,0x1(%rdi)
   0x00007ffff7b9145d <+61>:    movb   $0x1,(%rdi)

in __cxa_guard_release which sets _ZGVZ10save_stateiE6_foo_i to:
0x600a58 <_ZGVZ10save_stateiE6_foo_i>:    0x00000001

g++ -Os will give us:
   4005b4 <+0>:    cmpb   $0x0,0x20046d(%rip)        # 0x600a28 <_ZGVZ10save_stateiE6_foo_i>
   4005bb <+7>:    push   %rbx
   4005bc <+8>:    mov    %edi,%ebx
   4005be <+10>:    jne    0x4005e1 <_Z10save_statei+45>
   4005c0 <+12>:    mov    $0x600a28,%edi
   4005c5 <+17>:    callq  0x4004a0 <__cxa_guard_acquire@plt>
   4005ca <+22>:    test   %eax,%eax
   4005cc <+24>:    je     0x4005e1 <_Z10save_statei+45>
   4005ce <+26>:    lea    0x9(%rbx),%eax
   4005d1 <+29>:    mov    $0x600a28,%edi
   4005d6 <+34>:    mov    %eax,0x200460(%rip)        # 0x600a3c <_ZZ10save_stateiE6_foo_i>
   4005dc <+40>:    callq  0x4004c0 <__cxa_guard_release@plt>
   4005e1 <+45>:    cmpb   $0x0,0x200448(%rip)        # 0x600a30 <_ZGVZ10save_stateiE6_foo_j>
   4005e8 <+52>:    jne    0x400609 <_Z10save_statei+85>
   4005ea <+54>:    mov    $0x600a30,%edi
   4005ef <+59>:    callq  0x4004a0 <__cxa_guard_acquire@plt>
   4005f4 <+64>:    test   %eax,%eax
   4005f6 <+66>:    je     0x400609 <_Z10save_statei+85>
   4005f8 <+68>:    mov    %ebx,0x20043a(%rip)        # 0x600a38 <_ZZ10save_stateiE6_foo_j>
   4005fe <+74>:    mov    $0x600a30,%edi
   400603 <+79>:    pop    %rbx
   400604 <+80>:    jmpq   0x4004c0 <__cxa_guard_release@plt>
   400609 <+85>:    pop    %rbx
   40060a <+86>:    retq

And by the way, g++ tries to help us with

which is thread-safe static variable initialization.

If you don't need it - don't pay for it.

g++ -O2 -fno-threadsafe-statics
g++ -Os -fno-threadsafe-statics
will generate equal code:
   4004d4 <+0>:    cmpb   $0x0,0x20042d(%rip)        # 0x600908 <_ZGVZ10save_stateiE6_foo_i>
   4004db <+7>:    jne    0x4004ed <_Z10save_statei+25>
   4004dd <+9>:    lea    0x9(%rdi),%eax
   4004e0 <+12>:    movb   $0x1,0x200421(%rip)        # 0x600908 <_ZGVZ10save_stateiE6_foo_i>
   4004e7 <+19>:    mov    %eax,0x20042f(%rip)        # 0x60091c <_ZZ10save_stateiE6_foo_i>
   4004ed <+25>:    cmpb   $0x0,0x20041c(%rip)        # 0x600910 <_ZGVZ10save_stateiE6_foo_j>
   4004f4 <+32>:    jne    0x400503 <_Z10save_statei+47>
   4004f6 <+34>:    mov    %edi,0x20041c(%rip)        # 0x600918 <_ZZ10save_stateiE6_foo_j>
   4004fc <+40>:    movb   $0x1,0x20040d(%rip)        # 0x600910 <_ZGVZ10save_stateiE6_foo_j>
   400503 <+47>:    retq

The interesting part here is
movb $0x1, _ZGVZ10save_stateiE6_foo_i

Keep it simple.