Segmentation fault

I experienced that sometimes, web applications partly break with the following apache error log:

[Thu Oct 22 11:54:39 2009] [notice] child pid 17157 exit signal Segmentation fault (11)
[Thu Oct 22 12:00:06 2009] [notice] child pid 17158 exit signal Segmentation fault (11)
[Thu Oct 22 12:02:47 2009] [notice] child pid 17191 exit signal Segmentation fault (11)
[Thu Oct 22 12:02:47 2009] [notice] child pid 17343 exit signal Segmentation fault (11)

Whenever that error occurred, the server response is empty. In my case, that issue mostly happens in ajax requests where the server response should be some XML snippets. But if the segfault occurs, the XML snippet is empty – the onliest hint I get is the log entry in /var/log/apache/error.log.
First thing I tried is to debug applications using Zend Debugger, but if the debugger was enabled and I step through the application, the error did not happen and the request finishes correctly. Because Google did not lead to an answer, I sat down and tried until I was able to reproduce the error with a simple PHP script:

session_start();
class A
{
    public function __construct()
    {
        echo "A::__construct()";
    }

    public function __destruct()
    {
        $_SESSION["MyObject"] = $this;
        echo "A::__destruct()";
    }

    public function __toString()
    {
        return "CLASS_A";
    }
}
new A();

First time I called this script via web browser all things are good. But the second time, I get an segmentation fault error in the apache log and the browser just displays nothing. Reason for that is that I try to store the current object in the session variable. When I do this the very first time, it work’s because $_SESSION["MyObject"] is not defined. But for any further call, $_SESSION["MyObject"] is defined with the current object and it will be undefined in order to assign the new value. Thus A::__destruct() is called a second time, where $_SESSION["MyObject"] will be re-defined again. This results in a endless loop and ends up in a segmentation fault of the currently used worker thread of the apache webserver.
Note that in PHP 5.2 (and earlier?), there’s a Bug which causes a segmentation fault whenever a PHP function is called recursively more than a definit times. I tried to reproduced and got a segmentation fault after about 900000 recursions.
To do things right, we should check $_SESSION["MyObject"] whether it contains the current object. Only if $_SESSION["MyObject"] contains another object than the current, we can safely define another value!

session_start();
class A
{
    public function __construct()
    {
        echo "A::__construct()";
    }

    public function __destruct()
    {
        if($this !== $_SESSION["MyObject"])
             $_SESSION["MyObject"] = $this;
        echo "A::__destruct()";
    }

    public function __toString()
    {
        return "CLASS_A";
    }
}
new A();

Storing objects in session variables brings another issue: The destructor of each object stored in the session is called each time, the current script ends. But the constructor is never called, because the initialized object already exists in the session. In order to avoid the destructor call, I recommend to serialize the object by using serialize() before storing it in the session:

session_start();
class A
{
    public function __construct()
    {
        echo "A::__construct()";
    }

    public function __destruct()
    {
        $_SESSION["MyObject"] = serialize($this);
        echo "A::__destruct()";
    }

    public function __toString()
    {
        return "CLASS_A";
    }
}
new A();

In order to access the serialized object, you should unserialize the object first by using unserialize(). Please note, that no every object property can be serialized and should be handled separately. You can use PHP’s magic methods like __sleep() or __wakeup() to handle those properties.

Posted in PHP, Web Development | Leave a comment

Import Events into Google Calendar

This is a wrapper class for some Google calendar import methods. Frequently I get a list with lots of dates I’ve to add to the Google calendar. To bad that there is no calendar import function for the Google calendar. But fortunately, Zend provides a nice PHP framework for this task. Let’s have a look how to add calendar events by using this framework:

Requirements

My wrapper uses parts of the Zend framework. If you use gentoo just let portage do that task: emerge -av dev-php5/ZendFramework.
I’m sure that other distributions also maintain packages for that framework. If not, you’ve to install the Zend Framework by hand like desribed here.

You need at least a running PHP interpreter (here: dev-lang/php-5.2.10).

Parsing Data

Before we create an event, we’ve to organize data. This is done by creating corresponding objects:

$Match = new Match();
$Match->Number = 4265;
$Match->Location = "Hagwaldhalle Pfinztal, Ortsteil Kleinsteinbach";
$Match->Team = "VSG Kleinsteinbach";
$Match->Opponent = "TuS KA/Rüppurr II";
$Match->Date = new DateTime("06.03.2010 15:00");

Note, that you can use the static method Match::Parse($Path) in order to parse a data resource (given by $Path) with the following format:

4201 TuS Durmersheim III - TV Liedolsheim        03.10.2009 (15:00) Gymnasiumshalle Durmersheim
4202 TuS Durmersheim III - VSG Kleinsteinbach
4203 SG Hilpertsau/Au - TSV Ubstadt              03.10.2009 (15:00) Ebersteinhalle Obertsrot
4204 SG Hilpertsau/Au - SC Wettersbach

You can find a sample data file here.

Importing Data

Last step is to import the objects to your Google calendar. Check your Google calendar settings in order to get your private calendar ID (must be somewhat with @group.calendar.google.com as prefix).

Now, we have to login to the Google service. This can be done by Match::Login($Username,$Password). This method might throw exceptions on failures, so make sure you catch them in an appropriate way.

Finally you can create a calendar entry from a Match object by Match->Create($Feed). Where $Feed is the URL to your private Google calendar: http://www.google.com/calendar/feeds/ID@group.calendar.google.com/private/full.

Source & Example

You can checkout the latest version from Google code:
svn checkout http://matchimport.googlecode.com/svn/trunk/ matchimport-read-only.
There’s an example script run.php which contains the basic steps to import a Match schedule.

By default, the duration of a match is set to 100 mins and there’s a 20 min break between two matches. Further, a reminder is set which reminds the Google calendar user by SMS two days before the match starts.

The source is under Free BDS license, so feel free to modify the code.
Visit the Google code project for more details.

Posted in Volleyball, Web Development | Leave a comment

Using Both ondblclick & onclick Handlers

Back from hell after long I post a workaround for the ondblclick and onclick javascript issue:
It’s not possible to define both handlers so that the onclick handler won’t get active on a doubleclick:

<input type="button"
            value="Example"
            onclick="MethodA();"
            ondblclick="MethodB();" />
 

A possible workaround is to use a semaphore-like global variable (here: dblclick). This is set to true whenever the doubleclick handler is performed.
Further we delay the single click handler for some miliseconds (here: 250) and check against the dblclick semaphore until continue.

var dblclick = false;
function MethodA()
{
     setTimeout(function()
     {
          if(dblclick == true)
               return;

          alert('MethodA');
     },250);
}
function MethodB()
{
     dblclick = true;
     alert('MethodB');
     setTimeout(function()
     {
          dblclick = false;
     },250);
}
 
Posted in Web Development | Tagged , , , | Leave a comment

Fvwm Configuration

Fvwm Pager

Posted in FVWM | Leave a comment

Booting Gentoo from USB Hard Disk

I installed my Gentoo on my internal hard disk. Due to mobility I think about moving my system to a portable USB hard disk. The first idea was to use an initial ram disk image to load the USB drivers and load the main system. I read some things about creating an inital ram disk image (initrd) by using mkinitrd and come to the end, that there has to be a solution which is more easier than using an initrd.

The main problem when booting from USB is the following: First of all, the BIOS is setting up its USB drivers to load the kernel into the RAM. After this step, the BIOS makes the kernel booting. When the kernel is booting, it unloads the BIOS USB drivers to load the kernel specific USB drivers. There is some time between unload the BIOS drivers and loading the kernel drivers where no USB driver is active – without an USB driver, the kernel cannot access the root filesystem and panics.

The solution is to delay the kernel boot process until the kernel USB drivers are loaded and the kernel can access the root filesystem. I found the rootdelay boot parameter in my current kernel documentation:

rootdelay = [KNL] Delay (in seconds) to pause before attempting
to mount the root filesystem

So booting your linux distribution from an USB disk is quiet easy:

  • Just append the rootdelay parameter to your boot loader configuration (in my case, this is grub):

    # 2.6.22-suspend2-r1
    title 2.6.22-suspend2-r1
    root (hd0,1)
    kernel /boot/vmlinuz-2.6.22-suspend2-r1 root=/dev/sdb2 video=vesafb-tng:mtrr,ywrap resume2=swap:/dev/sdb5 rootdelay=5

  • When you boot your system from USB, you have to think about changing device names. If your device was at /dev/hda, the USB device will be at /dev/sda. So you have to figure out your USB device name, adjust the fstab configuration and the root kernel parameter in your grub configuration.
  • Finally you have to make sure, that you build-in the needed USB drivers into your kernel. So I set the following options in my kernel configuration:

    Device Drivers --->
    USB support --->
    < *> Support for Host-side USB
    [*] USB device filesystem
    < *> EHCI HCD (USB 2.0) support
    [*] Full speed ISO transactions (EXPERIMENTAL)
    [*] Root Hub Transaction Translators (EXPERIMENTAL)
    [*] Improved Transaction Translator scheduling (EXPERIMENTAL)
    < *> UHCI HCD (most Intel and VIA) support
    < *> USB Mass Storage support

  • It depends on your architecture whether you have to build-in EHCI, OHCI or UHCI. Just use lspci to detect you requirements. In my case I got the following output:

    ws1 linux # lspci | grep -i UHCI
    00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #1 (rev 01)
    00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #2 (rev 01)
    00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #3 (rev 01)
    00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #4 (rev 01)
    ws1 linux # lspci | grep -i OHCI
    ws1 linux # lspci | grep -i EHCI
    00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI Controller (rev 01)
    ws1 linux #

Posted in Gentoo | Leave a comment

Burning CD/DVD using the Shell

It’s not very difficult to write CD/DVD’s from the linux shell. Here’s is a short summary how to burn CD/DVD’s using mkisofs and cdrecord.

First of all, you have to create an ISO image, which you can write onto CD/DVD. I’m using mkisofs for this job:

mkisofs -J -v -r -o /tmp/myimage.iso /folder/to/burn
  • -v Verbose execution
  • -J Generate Joliet directory records in addition to regular iso9660 file names. (Windows compatibility)
  • -r Adapt file mode bits
  • -i Defines ouput image

After you created an ISO image, you can burn the image onto CD/DVD using cdrecord

cdrecord -v -eject -driveropts=burnfree -dao dev=/dev/hdc /tmp/myimage.iso
  • -v Increment the verbose level
  • -eject Eject the CD/DVD after process has finished
  • -driveropts=burnfree Turn on support for buffer underrun free writing
  • -dao Write your CD/DVD in Disk At Once Mode
  • -dev Define the device

That’s it – with increased verbose level, you can watch the process of your burn job.
Alternatively, you can create the image and burn the CD/DVD on the fly using linux pipes:

mkisofs -r /folder/to/burn | cdrecord -v -eject -driveropts=burnfree  dev=/dev/hdc -

In this case, mkisofs prints the image data to stdout. We catch this and redirect the image data directly to cdrecord. Note, that if mkisofs fails creating the image completely, cdrecord might rubish your CD/DVD.

Posted in Gentoo | Leave a comment

DigitalProductID Decode Algorithm

Every licence key, you give for Microsoft software, creates a DigitalProductID in the Windows registry. E.g. you find the digital product id for your Microsoft Windows in your registry: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion

The following algorithm shows you howto decode the digital product id to fetch your raw product key. If you loose your product key, this should help you to get it back without spending money. Please use this knowledge only for legal use! This is the onliest limitation to the following algorithm:

/* Digit Array */
Char[] Digits = {'B', 'C', 'D', 'F', 'G', 'H', 'J','K', 'M', 'P', 'Q', 'R', 'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9'};
Char[] DecodedKey = new Char[25];
System.Byte[] BinaryKey = {0x7f, 0x6a, 0x51, 0x4c, 0x8e, 0x5a, 0x91, 0x56, 0xea, 0x34, 0x77, 0x1a, 0xb7, 0xf2, 0x02}; // Not really a working key :-)
int StartOffset = 0x34;
int i, j, k;
String Result = "";
for (i = DecodedKey.Length-1; i >= 0; i --)
{
     k = 0;
     for (j = BinaryKey.Length-1; j >= 0; j--)
     {
          k = (k << 8) + BinaryKey[j];
          BinaryKey[j] = (System.Byte)(k / 24);
          k = k % 24;
     }
     DecodedKey[i] = Digits[k];
}

You got the raw decoded key in the Result variable. After decoding, you have to format the product key e.g. adding “-” after every 5th char and so on. I used Microsoft .NET Framework and C# to access the registry and decode the byte progression.

Posted in Windows | Leave a comment

Gentoo, Gnome & Vmware Trouble

After another world-update (Vmware Workstation 5.5.3 build-34685, D-Bus Message Bus Daemon 1.0.2) I got the following errors when I try to start vmware:

 

workstation1@ws1 /usr/local/bin $ /opt/vmware/workstation/bin/vmware
/opt/vmware/workstation/lib/bin/vmware: /opt/vmware/workstation/lib/lib/libpng12.so.0/libpng12.so.0: no version information available (required by /usr/lib/libcairo.so.2)
process 1777: Attempt to remove filter function 0xb6c80c20 user data 0x8805038, but no such filter has been added
D-Bus not built with -rdynamic so unable to print a backtrace
/opt/vmware/workstation/lib/bin/vmware: /opt/vmware/workstation/lib/lib/libpng12.so.0/libpng12.so.0: no version information available (required by /usr/lib/libcairo.so.2)
/opt/vmware/workstation/lib/bin/vmware: /opt/vmware/workstation/lib/lib/libpng12.so.0/libpng12.so.0: no version information available (required by /usr/lib/libcairo.so.2)
process 1788: Attempt to remove filter function 0xb7006c20 user data 0x8806c80, but no such filter has been added
D-Bus not built with -rdynamic so unable to print a backtrace
workstation1@ws1 /usr/local/bin $

It seems that there is a problem with the gnome dbus daemon running in background. There are several workarounds at web on vmware and gentoo pages which propose either to change soft-links linking corresponding libraries or start vmware with changed library dependings.
My workaround is quiet easy: Just stop the dbus daemon before starting vmware:

workstation1@ws1 /usr/local/bin $ cat /usr/local/bin/vmware
#!/bin/bash
sudo /etc/init.d/dbus stop
/opt/vmware/workstation/bin/vmware
sudo /etc/init.d/dbus start
workstation1@ws1 /usr/local/bin $

This will prevent you from changing any software preferences and is likely to be removed easily when this dbus vmware bug is hopefully fixed.

Posted in Gentoo, VMWare | 1 Comment

PHP Upload Script with Progress Bar

Introduction

If you want to upload some files through a web interface using PHP, you might use a classic POST method to push the data to the action script. If you choose your file and submit the HTML form, the file is transfered to the server and moved into a temporary file. Further your action script can examine the file and copy it to a specific location.
This method works fine, but I has one essential disadvantage: The file has to be transfered completely before you can examine the filetype, filesize and other file information. Further when transfering the file, you have no information about the transfer status. Assume, you want to upload a huge file. After you submit the upload form, you’ll wait several minutes without any information.
I found a solution which is working quiet well. I will post some examples and will desribe basic ideas about upload files using CGI PHP. Maybe you want to use this information to build your own upload script.

Using CGI PHP

There are different possibilities, you can run PHP. In general, PHP runs as module, e.g. in a apache web server. But there is another interesting method to run PHP. If you run a PHP script as CGI program, a new process is forked and the PHP interpreter is loaded into this process. This method allows us to run several PHP scripts concurrently.
Imagine, that we have a PHP script to transfer the file and periodically write out the size of transfered data into a temporary state file. Further another script exists to read out the state file information, calculate the percentage of transfered data and displays a cute progress bar. Now we can use the concurrency described above to let the two scripts run concurrently. So you see, the main idea is to separate the upload and the statistic script. While the upload script transfers data, the statistic script will show the progress bar.

Filetransfer Management

The idea of transfering is quit easy: We read a data package of a couple of bytes (e.g. 1024 bytes), examine it and save it in a temporary file. After we reach the end of file (eof), we move the temporary file to the destination file. You can get an idea of this transfer from the following code example:

#!/usr/bin/php
< ?PHP
// If the file size is too huge for uploading ...
if($_ENV['CONTENT_LENGTH'] > (1024^2) * 10)
{
     echo "Location: http://meinedomain.de/error.html\n\n";
     die(0);
}
$bytesTransfered = 0;
while(!feof(STDIN))
{
     $buffer = fread(STDIN,1024);
     $bytesTransfered += strlen($buffer);
     file_put_contents("/tmp/upload",$buffer,FILE_APPEND);
}
die(0);
?>

Note, that this script run as CGI program, like I desribed above.

As you see, I periodically read 1024 bytes from STDIN. This wrapps the input stream e.g. coming from a HTML input form. Let’s have a look at the input stream layout.
Further you are able, to validate the content length by using $_ENV['CONTENT_LENGTH'] at the beginning of the upload script, like I did on line 4.

Stream Data

If you look at the uploaded file, you will see something like the following snippet I got after uploading a jpeg file:
-----------------------------1951833994121914805585029106
Content-Disposition: form-data; name="datei"; filename="sysarc.jpg"
Content-Type: image/jpeg
some binary or ASCII code
-----------------------------1951833994121914805585029106--

As you see, we got the basic information Content-Disposition and Content-Type at the beginning of the file stream. So the idea is to parse the first lines of an incoming transfer until the header is completely transfered. Further one can examine the header information and perhaps, you can stop the file transfer, e.g. if someone wants to upload a forbidden content type.
To sum up, we have an upload control script, which can hand over essential information (filetype, filename, filesize, transfered bytes) to another statistic script. It’s your turn to create a statistic script which analysis this information.

Avoid Javascript

Now, you know the basic ideas about uploading files with pure PHP. You don’t need further client-side scripting languages like Javascript to use the upload script. Think about multiple frames (I know, that’s very old-school, but I found no other possibility). If your are using two frames, one frame can show the upload form and can call the upload script while the other frame can show the statistic page all the time. The statistic page refreshes itself every few seconds using the following html meta tag:

<meta http-equiv="refresh" content="5; URL=http://meinedomain.de/statistic.php">

If an upload begins, the upload script hands over upload information to the statistic script which creates an upload progress bar.

Posted in Web Development | Leave a comment