Ikke's Blog

Categories: Coding Corner, Docbook, Summer of Code 06

Dec 18
Gaim CVS and Bonjour using Avahi

So you want to play around with Gaim 2.0beta1 or CVS, you definately want the Bonjour/RendezVous protocol plugin to be able to IM with your buddies on your local LAN, but you haven't got Howl on your system as you believe Avahi is the way to go (good boy :-))?

Just apply this little patch. It's against current anoncvs from sf.net. You need to build avahi with avahi-compat-howl support.

Dec 16
GTK+ and Cairo is fun!

I've been playing with creating GTK+ widgets using Cairo lately. As I had to write some text for some bloody Word-task (university stuff) I started writing a widget for an "OXO" game, and make a little tutorial on how to make something alike. The task is done (I even had to remove some parts of the text :(), the tutorial isn't finished yet as there are some issues left with the widget.

Anyway, writing 2D drawing code using Cairo is really fun. Sometimes you need some maths to get some tasks done, but it's fun to experiment and the possibilities are almost endless.

Here's a little sample of what I got now, click on the image for a full-scale screenshot:

Some parts of the "logics" inside the widget are still buggy (-> the code to check whether a move is a winning one or not).

I start to get rid of the spammers on my blog. There's still some comment- and trackback-spam, but at least most spambots can't leech several gigabytes of my bandwith anymore. There are still requests done, but they get a 300byte answer, or even less.
One issue left: if I get 2 identical requests (same HTTP_REQUEST, HTTP_REFERER etc), one using HTTP/1.0 and one using HTTP/1.1, my mod_rewrite rules generate another response: 403 (5 bytes) when using HTTP/1.0, 301 (352 bytes) when using HTTP/1.1:

216.195.35.XX - - [16/Dec/2005:14:24:58 +0100] "GET /index.php/all?skin=stockholm HTTP/1.1" 403 5 "http://spamhost/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"
216.195.35.XX - - [16/Dec/2005:14:25:05 +0100] "GET /index.php/all?skin=stockholm HTTP/1.1" 301 352 "http://spamhost/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"

Can anyone explain me what causes this?

Thanks to RubenV who helped me out when creating the mod_rewrite rules :)

Dec 3
More valgrind abuse

After my previous article on Valgrind I started using it more and more, and discovered another nice feature of it. Just check this sample:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define MESSAGE "test"

int main(int argc, char *argv[]) {
        char *t = NULL;

        /* Hey, everyone makes mistakes */
        t = (char *)malloc(strlen("" MESSAGE) * sizeof(char));
        assert(t != NULL);
        strcpy(t, "" MESSAGE);

        printf("%s\n", t);

        free(t);

        return 0;
}

Compiling and running looks ok:

$ gcc -g -Wall -Werror -o test2 test2.c
$ ./test2
test

But luckily there's Valgrind to tell us the code is horribly wrong:

$ valgrind --tool=memcheck ./test2
==13483== Memcheck, a memory error detector for x86-linux.
==13483== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==13483== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==13483== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==13483== For more details, rerun with: -v
==13483==
==13483== Invalid write of size 1
==13483==    at 0x1B906485: strcpy (mac_replace_strmem.c:199)
==13483==    by 0x80484B2: main (test2.c:14)
==13483==  Address 0x1BA5C02C is 0 bytes after a block of size 4 alloc'd
==13483==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==13483==    by 0x8048472: main (test2.c:12)
==13483==
==13483== Invalid read of size 1
==13483==    at 0x1B968B6B: _IO_vfprintf (in /lib/tls/libc-2.3.5.so)
==13483==    by 0x1B96DF36: _IO_printf (in /lib/tls/libc-2.3.5.so)
==13483==    by 0x1B93DF36: __libc_start_main (in /lib/tls/libc-2.3.5.so)
==13483==  Address 0x1BA5C02C is 0 bytes after a block of size 4 alloc'd
==13483==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==13483==    by 0x8048472: main (test2.c:12)
test
==13483==
==13483== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 13 from 1)
==13483== malloc/free: in use at exit: 0 bytes in 0 blocks.
==13483== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
==13483== For a detailed leak analysis,  rerun with: --leak-check=yes
==13483== For counts of detected errors, rerun with: -v

This should be fairly self-explaining... I guess most C programmers forgot to allocate strlen(msg)+1 (the end '\0') at least once in their life...

By the way: hello Planet Grep :-)

Nov 19
Small Valgrind introduction

Everyone writing C or C++ code should know what a memory leak is. You allocate some memory, and never free it.
It can be very hard to make your code memleak free, or even just to know whether your code contains any memleaks.
Luckily, in the Free Software world, we got a great tool to check our code for memleaks (or other errors): Valgrind.

As I don't have time to write a lot now, I'll just give a very simple sample of it's usage.

Here's my code (very bad code, obviously, but hey ;-)):

#include <stdio.h>
#include <stdlib.h>

static void function() {
        char *test = (char *)malloc(100 * sizeof(char));
        test[0] = '\0';

        printf("Function\n");

        /* Leaking 100 chars here, 100 bytes */
}

int main(int argc, char *argv[]) {
        int *i = NULL;

        function();
        i = (int *)malloc(50 * sizeof(int));
        printf("Done\n");

        return 0;

        /* Leaking 50 ints here. On x86, this is 50*4=200 bytes */
}

As you can see, we leak memory twice: once 100 bytes, once 200.
Let's compile and run our code:

$ gcc -o test -Wall -g test.c
$ ./test
Function
Done

Great, our code works fine (or at least, it looks like it).

Now we introduce valgrind. First we'll do a simple memory allocation check:

$ valgrind --tool=memcheck ./test ==18819== Memcheck, a memory error detector for x86-linux.
==18819== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==18819== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==18819== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==18819== For more details, rerun with: -v
==18819==
Function
Done
==18819==
==18819== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==18819== malloc/free: in use at exit: 300 bytes in 2 blocks.
==18819== malloc/free: 2 allocs, 0 frees, 300 bytes allocated.
==18819== For a detailed leak analysis,  rerun with: --leak-check=yes
==18819== For counts of detected errors, rerun with: -v

Valgrind tells us we leaked 300 bytes, in 2 blocks (one malloc call returns one block, obviously).
It also tells us to re-run the test with the --leak-check=yes flag, which is a good advice:

$ valgrind --tool=memcheck --leak-check=yes ./test
==18826== Memcheck, a memory error detector for x86-linux.
==18826== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==18826== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==18826== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==18826== For more details, rerun with: -v
==18826==
Function
Done
==18826==
==18826== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==18826== malloc/free: in use at exit: 300 bytes in 2 blocks.
==18826== malloc/free: 2 allocs, 0 frees, 300 bytes allocated.
==18826== For counts of detected errors, rerun with: -v
==18826== searching for pointers to 2 not-freed blocks.
==18826== checked 1404368 bytes.
==18826==
==18826== 100 bytes in 1 blocks are definitely lost in loss record 1 of 2
==18826==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==18826==    by 0x80483B5: function (test.c:5)
==18826==    by 0x80483F4: main (test.c:14)
==18826==
==18826==
==18826== 200 bytes in 1 blocks are definitely lost in loss record 2 of 2
==18826==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==18826==    by 0x8048400: main (test.c:15)
==18826==
==18826== LEAK SUMMARY:
==18826==    definitely lost: 300 bytes in 2 blocks.
==18826==    possibly lost:   0 bytes in 0 blocks.
==18826==    still reachable: 0 bytes in 0 blocks.
==18826==         suppressed: 0 bytes in 0 blocks.
==18826== Reachable blocks (those to which a pointer was found) are not shown.
==18826== To see them, rerun with: --show-reachable=yes

Great, here Valgrind tells us exactly what we're doing wrong.
There are 2 blocks where we leak memory:

  • The first one is at code path
    main (test.c:14) -> function (test.c:5) -> malloc (vg_replace_malloc.c:131)
    leaking 100 bytes.
    The vg_replace_malloc.c file isn't ours, it's a valgrind file where the malloc() wrapper (which keeps track of our allocations/free's/...) is located. We're mostly interested in the "function (test.c:5)" part. If we look at line 5, we see this is

    char *test = (char *)malloc(100 * sizeof(char));
    our first allocation. And indeed, if we look further, we never free these 100 chars.
  • Second is at main (test.c:15). Again, we can look at this line:
    i = (int *)malloc(50 * sizeof(int));
    and indeed, we never free these allocated integers again. We allocated 50 ints, and on x86 one int is 32 bits (4 bytes), so we leak 200 bytes (and valgrind was correct once again :-)).

Obviously, valgrind got much more options or checks:

$ valgrind
valgrind: Missing --tool option
Available tools:
        memcheck
        addrcheck
        cachegrind
        corecheck
        helgrind
        massif
        lackey
        none
        callgrind
valgrind: Use --help for more information.

I don't know all of them, actually I only use the memcheck thing, but even when only using one tool, it can be a very useful program.

I got one minor issue with valgrind currently: when it detects memory leaks in some program, it still returns 0 in the end, so it's not easy to integrate valgrind checks in automake's "make check" target. If someone got any pointers how to do this, please let me know!

Nov 5
Maemo and mDNS

Porting Avahi to the Maemo platform seems to be quite hard (if not impossible) because of the DBUS version conflict (Avahi needs DBUS >= 0.34, whilst the Maemo platform is still based on DBUS 0.2x). There's a DBUS 0.3x branch in Maemo's SVN repository, but that's not stable yet, and will only be used in the InternetTablet2006 releases, so I gave up on Avahi for now :oops:.
Instead, I'm trying to create a good package of Howl now (I know, I don't like the Howl API either), then I'll attempt to build a small (Hildon?) application on top of it, just as a test case for "the real thing" ;-)

*edit*
It works inside my scratchbox (i386) :-)
Built an arm deb package too, installed it on my "real" device, the software runs (no ld errors), but I couldnt test it yet as I don't have a wireless network at home, and didn't manage to get USB networking working yet :-(

<< Previous Page :: Next Page >>

Categories

Who's Online?

  • Guest Users: 400

Misc

XML Feeds

What is RSS?