About

All articles, tagged with “agile”

m0cxx0r And Return Types

The core of m0cxx0r is the creation of an object that records method calls and compares them to expectations. This is done by using C++ placement new to create a VTableDonor object in allocated memory the same size as the object being mocked and then returning the memory as a m0cxx0r::Mock class which inherits from T, the class of the object being mocked.

When methods are called on the mock object instead of invoking the methods in T, the virtual methods in VTableDonor are called instead and are able to record the calls made and compare them to expectations. The problem is that the signature of the original method and the VTableDonor method may not match.

In order to be able to find and compare parameters the VTableDonor methods take a single parameter which they can use as a fix point to find other parameters that may be passed to the call via pointer arithmetic. Luckily the rules for parameter layout are fairly simple, so if you know the address of the first parameter, it’s easy to find the others.

Unfortunately the same isn’t true for return values. Depending on the return type, space for the return value might be pushed on to the stack as a hidden parameter, a pointer to a heap location might be pushed or the caller may expect the return to be saved in a register. The rules for which mechanism is used depends on some combination of the compiler, platform and sometimes which C++ features the return type uses. To make matters worse the this pointer is also pushed as a hidden parameter which can become corrupted when there is a return type mismatch. All of this makes it very difficult to call a VTableDonor virtual method with a void return type in place of a virtual method on T with a non-void return type and have everything work correctly. You can see why people generally use the much simpler C ABI to nail binaries together.

After a lot of research and some trial and error I’ve managed to get m0cxx0r working with virtual methods returning primitive types and non-POD types by value in Visual Studio 2005 on Windows and using g++ 3.3 on Linux. The new code can be found here. I’m still having trouble getting it working on g++ 4.0.1 on Darwin where dyld seems to be noticing my monkeying around, causing the process to exit with a dyldmisaligned_stack_error — hopefully it will be possible to work around.

A potentially better solution is used by mockitopp, a brand new dynamic mock framework for C++ that I found on my travels around the internet today. Where m0cxx0r uses a compiler generated VTableDonor class and then attempts to work around the signature mismatch problems, mockitopp builds the mock vtable at run time which has the advantage that the entries can be made to match the signatures in the class being mocked. It looks to be a promising approach and I’m looking forward to investigating mockitopp further.

m0cxx0r on Windows

In order for m0cxx0r to be useful for writing tests at Linden Lab, it needs to work on all of the platforms that we target with C++ applications, so today I tried building and running m0cxx0r on Windows.

Initially it looked good: m0cxx0r built in the default Visual Studio Debug configuration, but then crashed on construction of Mock objects due to accessing unitialised memory. This was relatively easy to fix, just requiring a call to memset to zero out the memory that would become the m0cxx0r::Mock object.

The next problem was harder to fix. One of the hacks at the core of m0cxx0r is pointing the mock object’s vptr at a donor vtable populated with methods that record calls to the methods. The problem is that the signatures of the original and replacement methods may not match, so multiple parameters may be passed to a method expecting a single parameter. This shouldn’t be a problem as long as the caller manages the stack unwinding: the caller just pushes parameters on to the stack which are ignored and then popped the back off again.

Although m0cxx0r just worked when compiled with GCC on darwin, the run time checks performed in Debug by Visual Studio caught the stack pointer mismatch and stopped execution. In Release the situation was even worse: the tests just crashed out without error. Luckily after some poking around I was able to turn of the stack pointer run time check in Debug and after some trial and error I found that disabling optimisations in the Release configuration with the default __cdecl calling convention allowed the tests to run without error in Release.

With these property changes made, m0cxx0r built and ran it’s tests fine in Visual Studio 2005 on Windows. Get the Visual Studio 2005 project and solution files along with the m0cxx0r code from Google Code.

Anything But Java

The Shakespeare Language

Last week I was invited to talk at JAOO Denmark. Originally a Java conference, JAOO is now a very broad software development conference covering everything from agile to language design to distributed systems.

The stand out talk on the first day was Gregor Hohpe‘s Programming the Cloud which enumerated some of the problems with building distributed systems without call stacks, transactions, promises, certainty or ordering constraints and then outlined some approaches to overcome them including looking at real life situations which also have to deal with the lack of distributed transactions. For example at Starbucks your coffee is made concurrently with your payment being taken and then problems are fixed up afterwards if you can’t pay, they can’t make the coffee or they get the order wrong. The throughput gained from optimistic concurrency is greater than the loss of having to fix things up, even if it means that sometimes you end up giving away free coffee.

Unfortunately I missed Lars Bak’s V8 keynote on Tuesday, but was really impressed by Successfully Applying REST by Stefan Tilkov which enumerated REST patterns and anti-patterns shining some light on the subtleties of a technology which initially seems straight forward but turns out to have some pot holes for the unwary.

The highlights on Wednesday were seeing Guy Steele and Dick Gabriel give their 50-in-50 talk again (which is still not available on-line, but one of the highlights is here) and seeing the new WeDo lego robotics platform for kids which will be available next summer. The most relevant talk was Test Driven Development, Take 2 by Erik Doernenburg which got me thinking about how to do dynamic mock objects in C++. My talk on embedding Mono in Second Life went down well and elicited some good questions, although as a fringe topic it wasn’t heavily attended.

Other highlights included Erik Meijer’s keynote on fundamentalist functional programming, Bill Venners talk on Scala, hearing Patrick Linskey conclude that the way to make Java scale is to use Scala or Erlang, James Copland reinventing OO, playing guitar at the jam session and hearing Erik suggest to Lars that we compile LSL to CIL and run it on V8 modified to capture thread state while Erik was spilling half bottles of Champagne over people and Lars was swaying and stumbling around the room.