Multiplay Labs

tech hits and tips from Multiplay

Archive for the ‘Code’ Category

When optional method parameters aren’t optional in C#

without comments

So csharp added optional parameters in C# 4.0 which is great no more adding loads of method signatures when you want to add an additional parameter to an existing method, or so I thought.

While working on TShock I used optional parameters to extend the functionality of existing methods in the core API, to my surprised I started seeing reports of existing plugins failing with missing method exceptions. After some investigation I discovered that the way C# implements optional parameters is it bakes the defaults into the caller and not into the callee.

The result of this is that until all existing code is recompiled against the updated API, it will fail to run. Not only this but if you update the defaults values of your optional parameters then again all code must be recompiled, not just that containing the update, to ensure the new values are always used.

Clearly this is a PITA for public API’s so wanted to mention it so others are aware of this significant gotcha with optional parameters in csharp.

Written by Dilbert

March 3rd, 2012 at 4:19 pm

Posted in CSharp

Tagged with , ,

Building DBD::mysql under Cygwin with mysql 5.5

without comments

The following instructions will enable you to build DBD::mysql under Cygwin using mysql 5.5 sources.

1. First download the latest mysql source from http://dev.mysql.com/downloads/mysql/
2. Expand the source and change into the directory e.g. tar -xzf mysql-5.5.21.tar.gz; cd mysql-5.5.21
3. Prepare the Makefiles using cmake, we need to disable shared libs to avoid having to mess with LD_LIBRARY_PATH.

cmake . -DCMAKE_LEGACY_CYGWIN_WIN32=0 -DCMAKE_INSTALL_PREFIX=/usr/local -DDISABLE_SHARED=1

4. Build the client and libs:

make mysqlclient libmysql

4.1. If the build errors with duplicate definition for dtoa, then you can fix it by commenting out the cygwin definition in: /usr/include/stdlib.h (dont forget to remove the comment when done)
5. Install mysql components

sh -c 'for dir in client libmysql scripts include; do cd $dir; make install; cd -; done'

6. Build and install DBD::mysql via CPAN, if you don’t have a running mysql instance you may need to “force” install

perl -MCPAN -e shell
cpan[1]> install DBD::mysql

Written by Dilbert

February 29th, 2012 at 9:29 pm

Posted in Cygwin,Perl

Tagged with , , ,

Updated contextual help in WordPress

without comments

If you’re like me and you try to be a good citizen when it comes to writing wordpress plugins, then you’ll write some contextual help/documentation for them that shows up in the appropriate places of the wordpress admin interface.

Since the wordpress 3.3.1 update however, the previous method I used of doing this resulted in the help permanently appearing on the pages in question. When you have a lot of plugins and a lot of help text, that can result in the actual admin interface being several full page scrolls away, which can be pretty annoying.

As such, I recently worked out how to quickly adapt the old simple style of adding contextual help to make use of the newer system.

Before:

// add some contextual help in for add/edit post admin pages
add_action('load-post-new.php', 'myplugin_help');
add_action('load-post.php', 'myplugin_help');
 
function myplugin_help() {
   add_filter('contextual_help','load_myplugin_help');
}
 
function load_myplugin_help($help) {
    echo $help;
    echo "My custom plugin help";
}

After:

// add some contextual help in for add/edit post admin pages
add_action('load-post-new.php', 'myplugin_help');
add_action('load-post.php', 'myplugin_help');
 
function myplugin_help() {
   add_filter('contextual_help','load_myplugin_help');
}
 
function load_myplugin_help($help) {
    get_current_screen()->add_help_tab( array(
        'id'        => 'myplugin-help',
        'title'     => __('My Plugin Help'),
        'content'   => "Help for my plugin"
    ) );
}

The benefit of this new way is that the new system nicely sorts all the help into little menus, so rather than having all of your help on one massive page, the help dropdown at the top of the admin interface provides a menu for each plugin, allowing the help section to take up less space and generally be more usable.

Written by Andrew Montgomery-Hurrell

January 16th, 2012 at 2:56 pm

Posted in Code,PHP,Wordpress

Tagged with

php Segmentation fault (core dumped) in xmlFreeMutex

without comments

Having just rebuilt a clean install of php 5.3.6 it was crashing left right and center even a php -m caused it.

The stack looks like the following under gdb

#0 0x0000000103db8600 in ?? ()
#1 0x0000000100ce1a95 in xmlFreeMutex () from /usr/local/lib/libxml2.so.5
#2 0x0000000100ce14d5 in xmlCleanupGlobals () from /usr/local/lib/libxml2.so.5
#3 0x0000000100c79f4a in xmlCleanupParser () from /usr/local/lib/libxml2.so.5
#4 0x000000000044daa8 in php_libxml_shutdown ()
#5 0x000000000044dad9 in zm_shutdown_libxml ()
#6 0x000000000055289f in module_destructor ()
#7 0x0000000000559be4 in zend_hash_apply_deleter ()
#8 0x0000000000559e58 in zend_hash_graceful_reverse_destroy ()
#9 0x000000000054dfc8 in zend_shutdown ()
#10 0x00000000004fbb9a in php_module_shutdown ()
#11 0x00000000005d55e2 in main ()
#12 0x0000000000417125 in _start ()

The problem is being caused by libxml2 under FreeBSD being compiled as threaded by default where as php isn’t.

The fix is simple select the LINKTHR option from make config and recompile php and its modules to be safe 🙂

Written by Dilbert

June 16th, 2011 at 11:47 am

Posted in FreeBSD,PHP

“version” perl Module Upgrade on SFU results in broken perl!

without comments

For those of you who use SFU, a useful POSIX layer thats freely available for Windows that want to update / install new perl modules using CPAN, be aware that the updated the “version” module can lead to a broken perl install. The resulting symptoms are that perl commands hang doing nothing. The cause of this is that you end up with two “version” module folders, one lower case “version” and one upper-case “Version”.

The fix is simply to remove the old “Version” folder from /usr/local/lib/perl5/site_perl//x86-interix-thread-multi/auto/

Written by Dilbert

June 1st, 2011 at 7:56 pm

Posted in Perl

Elusive error in rack randomly triggered by uploads

without comments

For a while now I’ve been trying to deal with a bizarre issue with rails where uploads would, apparently at random, cause a server error. The error would report a ‘bad content’ error and often the upload would nearly complete as far as the user was concerned, only to fall at the last hurdle, bailing out at 99%. This happened pretty infrequently and I could never seem to replicate it but I eventually found an article that explained the problem we seemed to be having.

Heisenbug: Ruby on Rails Corrupted/Broken POST data on a big form, it’s all Rack’s fault

In the above article, it’s explained that there is an odd bug in a specific version of rack that only gets triggered in very specific cases where multipart form boundaries happen to align with multipart content parser’s buffer size.

A fix can be found in later versions, as show in this commit: Fixed multipart parameter parsing for when a field’s body ends at the same time as a chunk (i.e. we’ve reached EOL and buffer is empty)

Once you read the code and understand the context, it becomes clear from the commit why the error was occurring. Essentially the parser was thinking it had reached the end of the document if it just so happened that the data so far was perfectly aligned in the buffer instead of also assuring that it wasn’t just at the end of a field, rather than the entire document.

It’s an incredibly annoying and hard to diagnose error, especially since, from a high level view all the way at the frontend of a rails app, it’s extremely unclear as to what is triggering it. It was causing nginx to spout out 422 errors which lead me down the path of suspecting it was the user’s clients prematurely terminating the upload connection, which wasted some time, but no, eventually it turned out to be this peculiar boundary alignment bug. Keeping any eye out to see whether or not any more issues crop up, but hopefully that has solved it.

On a side note, it seems odd that rack is using such a small buffer size of only 16k. For processing large uploads that seems to put an unnecessarily high amount of I/O load on the server considering the amount of times it has to do reads from files potentially upwards of several gigabytes. Once we’ve seen more evidence that this bad content issue has gone away it might be worth adjusting this value to make it more appropriate for processing large multipart data payloads.

Written by Andrew Montgomery-Hurrell

December 20th, 2010 at 5:15 pm

Posted in Rails

When unlink in perl doesn’t actually remove the file…

without comments

Ok so this was a weird one, we where using unlink in perl and it was returning success yet the file still exists, so what gives?

After much hunting and digging it turned out to be a nice little gotcha about the way unlink works under cygwin and hence is inherited by their perl implementation.

The basic crux is that in order to be a unix link as possible cygwin makes use of the delete on close function within windows to attempt to delete files that are shared locked by other applications. The result is that even though the file is reported as deleted it is only marked as pending deletion and will only actually be deleted when the last the shared lock counter reaches zero.

Unfortunately its easy for this to fail if the other locking application makes a change to the file the delete request will be silently discarded.

So there you have it, cygwin + perl + unlink = files delete some times, you have been warned.

For more info on the internals see the following: Re: Inconsistent behaviour when removing files on Cygwin

Written by Dilbert

December 7th, 2010 at 12:33 am

Posted in Code,Hackery,Perl

PHP class_exists fails to return for missing dependent classes

without comments

If you call class_exists( $sClass ) which in turn triggers an autoloader that fails to load a dependent class of $sClass e.g. where $sClass extends a missing class, then class_exists fails silently and never returns.

Note this only fails on missing dependent classes if the original class fails to load then class_exists returns false as expected.

The following code demonstrates the bug:
AutoLoader.php:

<?php
class AutoLoader
{
    // Public Methods
    public static function factory( $sClass )
    {
        error_log( "factory: $sClass" );
        if ( class_exists( $sClass ) )
        {
            error_log( "Class Exists" );
            return new $sClass;
        }
        error_log( "Failed to autoload: $sClass" );
        return null;
    }
    public static function autoload( $sClass )
    {
        // NOTE: its unclear if the return codes of autoload functions are ever used?
        error_log( "autoload: $sClass" );
        if ( class_exists( $sClass, false ) )
        {
            error_log( "Already loaded" );
            return true;
        }
        error_log( "including: $sClass" );
        $iRet = @include_once( "$sClass.php" );
        error_log( "included: $iRet for $sClass, " . class_exists( $sClass, false ) );
 
        return class_exists( $sClass, false );
    }
}
 
// Register our Autoloader
spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
 
$oMyClass = AutoLoader::factory( 'MyClass' );
if ( $oMyClass )
{
    error_log( "Got object:" . get_class( $oMyClass ) );
}
else
{
    error_log( "Failed to load 'MyClass'" );
}
?>

MyClass.php

<?php class MyClass extends MyBaseClass {} ?>

This bug is registered here: http://bugs.php.net/bug.php?id=53036

Written by Dilbert

October 10th, 2010 at 4:22 pm

Posted in Code,PHP

PayPal PHP SOAP Interface Memory Leak Fix

without comments

Due to the fact that the PayPal SOAP interface relies heavily on exceptions within pear its call to backtrace quickly causes a significant memory leak resulting in long running processes exiting with something like:
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 13 bytes) in /usr/local/share/pear/PEAR.php on line 884

Fortunately the fix is quite simple:-

--- /usr/local/share/pear.old/PEAR.php.orig     Tue Feb  2 18:47:42 2010
+++ /usr/local/share/pear.old/PEAR.php  Tue Feb  2 23:24:45 2010
@@ -860,7 +862,7 @@
         $this->userinfo  = $userinfo;
         if (function_exists("debug_backtrace")) {
             if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
-                $this->backtrace = debug_backtrace();
+                $this->backtrace = debug_backtrace( false ); // Don't populate the object reference as this causes circular reference and hence memory leak
             }
         }
         if ($mode & PEAR_ERROR_CALLBACK) {

Written by Dilbert

October 4th, 2010 at 4:24 pm

Posted in Code,PHP

A Great CSS Gradient Generator Tool

without comments

Found this the other day and its a great little tool for generating CSS gradients 🙂

Written by Dilbert

June 21st, 2010 at 9:20 pm

Posted in HTML & CSS