Friday, December 21, 2007

BHO.CVX Trojan

My friend got this on his computer. The most annoying thing for him was that his antivirus software would popup a warning message about this Trojan every now and then.

The BHO probably stands for Browser Helper Object; I could find it inside the Add-ons to IE, but deactivating it didn't help. Thankfully the antivirus was yelling which file the Trojan is in, it couldn't delete it because it was in use. Even in safe mode the file was locked.

I was able to delete it from command line after booting up the computer using windows install CD and choosing Recovery mode (or sth like that, I have German Windows :) ).

Sunday, December 16, 2007

Evil locale

.NET is trying to protect developers from making simple mistakes while providing them with all sorts of non obvious problems completely for free.

The simple mistake is trying to mutate a struct returned by a property. Line 14 in the example code raises compile time error. This line is otherwise completely fine except that it doesn't make sense -- the Start property is returning a copy of the value type Point.

 1 struct Point {
 2     public int x;
 3     public int y;
 4 }
 5 class Line {
 6     Point start;
 7     Point end;
 8     public Point Start {get {return start;}}
 9     public Point End {get {return end;}}
10 }
11 public class Main {
12     public static void Main() {
13         Line l = new Line();
14         l.Start.x = 2
15     }
16 }

The example comes from here The page explains that in such a case IronPython will also fail (by design) with an error.

Now about the free errors. They are all sponsored by the evil locale. Parsing in .NET takes the operating system's locale into account. In Poland the floating point numbers are written using coma instead of a dot. So 2.3 is written as 2,3. Trying to parse your settings file containing floats on a computer with Polish locale will throw an exception if there are any dots in them.

But it is not just parsing. If you invoke ToUpper on a string it also takes locale into account. In Turkey they have dotted i and dotless ı. The letter i (the dotted one obviously) has upper case equivalent which has a dot above it (expressible in unicode). If you have good fonts you should be able to see it right here: İ.

One more thing, when dealing with DateTime think about Buddhist Era in Sri Lanka :).

Saturday, December 8, 2007

Resolver One - Beta

There are plenty of languages laying around. They are tools with advantages and disadvantages. Knowing them allows us to know which are best to the job at hand. Recently I reflected on which languages would I use for different tasks.

If I had an idea for a killer web site I would go with Ruby on Rails. I have done one app using it and was very happy with it.

If I were making a windows app, I would code against .NET. The language of choice for this task would be Nemerle. Nemerle is a functional language with powerful macros (don't confuse with C macros) targeted at .NET Framework.

What would I use to add some processing to a spreadsheet? Python would be my first choice :). Resolver One allows to script a spreadsheet with Python. The Beta has just been released [download].

Saturday, November 24, 2007

Extract variable in Vim

I have automated the extract variable refactoring in Vim. Well, at least for languages where you don't have to declare types. This includes Python, the language I use at work. It can also be used with Ruby and other dynamic languages, as well as with languages featuring type inference, like Nemerle and Haskell.

Select (in visual mode) a value you want to extract, and press ctrl-e. This will pop up a dialog asking for the name of the variable. A line with the assignment will be added above and all occurrences of the value will be replaced with the given name. The replacement will happen only in the lines after the assignment.

To enable it, copy the snippet to your vimrc file.

function! ExtractVariable()
    let name = inputdialog("name please")
    if name != ""
        execute "normal O" . name . " = "
        normal p
        execute (line('.')+1) . ",$s/" . escape(getreg('"'), '/\') . "/" . name . "/" 

noremap <c-e> y:call ExtractVariable()<cr>

Monday, October 22, 2007

Distributed build

I have created a set of scripts to run tests on many computers at the same time. This allows us to commit much sooner than before. You can read more about distributed build and our build system in general in Michael Foord's blog post.

The basic idea is to store the names of the tests to run in a database, and copy the source tree to a couple of machines. A machine would sign up for one test at a time and report results.

Friday, September 28, 2007

Swap parameters script for Vim

I have published a script for Vim. The script is written in python. The job of the script is to swap parameters. A user can swap a parameter under the cursor with the next one (gs) or with the previous one (gS). One can also use this command preceded with count. If I wanted to swap first parameter of a function with the third, I would type 2gs.

The possibility of writing scripts for vim in python not only made it very easy for me to write that script, but also allowed for easy testing. I used py.test framework and made a suite of quite literate tests. Below is a beautified set of use/test cases generated from the tests.

Left column contains the line before typing gs, the right shows the result. Position of the cursor is depicted with green background.

fun(parm1, parm2) fun(parm2, parm1)
fun(parm1(), parm2) fun(parm2, parm1())
fun(parm1(), parm2) fun(parm2, parm1())
fun(parm1(arg,arg2), parm2) fun(parm2, parm1(arg,arg2))
fun(parm1(arg,arg2), parm2) fun(parm2, parm1(arg,arg2))
fun(parm1(arg,arg2), parm2) fun(parm2, parm1(arg,arg2))
fun(parm1(arg, arg2), parm2) fun(parm2, parm1(arg, arg2))
fun(arg1, arg2, arg3) fun(arg1, arg3, arg2)
array[arg1, arg2] array[arg2, arg1]
fun(parm1[], parm2) fun(parm2, parm1[])
fun(parm1[], parm2) fun(parm2, parm1[])
fun(parm1, array[]) fun(array[], parm1)
fun(a,b) fun(b,a)
[(p1, p2), p3] [p3, (p1, p2)]

Test cases for gS -- swap backwards.

fun(parm2, parm1) fun(parm1, parm2)
fun(parm2, parm1()) fun(parm1(), parm2)
fun(parm2, parm1()) fun(parm1(), parm2)
fun(parm2, parm1(arg,arg2)) fun(parm1(arg,arg2), parm2)
fun(parm2, parm1(arg,arg2)) fun(parm1(arg,arg2), parm2)
fun(parm2, parm1(arg,arg2)) fun(parm1(arg,arg2), parm2)
fun(parm2, parm1(arg, arg2)) fun(parm1(arg, arg2), parm2)
fun(arg1, arg2, arg3) fun(arg2, arg1, arg3)
fun(arg1, arg2, arg3) fun(arg1, arg3, arg2)
array[arg2, arg1] array[arg1, arg2]
fun(parm2, parm1[]) fun(parm1[], parm2)
fun(parm2, parm1[]) fun(parm1[], parm2)
fun(array[], parm1) fun(parm1, array[])
fun(b,a) fun(a,b)

In the tests I mark the position of the cursor by enclosing a character with || symbols. Here is the first test.

  5     def test_simple_case(self):
  6         self.assertSwaps("fun(par|m|1, parm2)",
  7                             "fun(parm2, parm|1|)")

Monday, August 27, 2007

What happens during MessageBox.Show()?

Last Friday my pair-programming partner said that System.Windows.Forms.Timer has reentrance problem. By reentrance I mean a situation where during processing of one tick generated by a timer, another tick is triggered and now both are processed simultaneously (which was bad in our case). For this to happen the processing of some tick needs to take longer than the interval set on the timer. After I expressed my doubts about winforms timer having this issue, he skilfully put together an example, sth like the following.

 1 #pragma indent
 3 using System.Windows.Forms
 4 using Nemerle.IO
 6 def form = Form()
 7 def timer = Timer()
 8 timer.Interval = 5000
 9 timer.Tick += (_,_) => print(MessageBox.Show("bum!"))
10 form.Shown += (_,_) => timer.Start()
11 Application.Run(form)

The code is written in the Nemerle programming language, but that is not important. In line 9 a function is defined and attached to handle the tick event. As a consequence, on each tick the following code is executed. print(MessageBox.Show("bum!")) I used the print statement just to make it obvious that this function doesn't return until user closes the msgbox.

Anyway, I was certain that it will prove there is no reentrance problem. However contrary to my expectations, those unbearable message boxes started to pop up, stacking on one another.

Now a little bit about the winforms timer. The handlers attached to the tick event are executed on the GUI thread. Each time the interval elapses, the timer adds an "execute handlers attached to me" event to the event queue. This should guarantee no reentrance since events on the queue are processed one by one.

Processing of an event triggered by the timer can't complete until the messagebox closes. So, it seems that with each new messagebox we have new event being processed. How can that be?

Well, there is a static method on Application class, called DoEvents. You can call it from inside of a method handling some event. Tha MessageBox.Show must be doing sth similar. I wasn't able to reflect into that, because the displaying of the messagebox is eventually delagated to a non managed code. It looks sth like the following but I have deleted some lines.

 1 Application.BeginModalMessageLoop();
 2 try
 3 {
 4     result = Win32ToDialogResult(SafeNativeMethods.MessageBox(new HandleRef(owner, handle), text, caption, type));
 5 }
 6 finally
 7 {
 8     Application.EndModalMessageLoop();
 9 }
10 return result;

As far as I can tell BeginModalMessageLoop() should be rather named PrepareForModalMessageLoop(), because what it does is mainly to disable (gray out) all the forms in the application, EndModalMessageLoop(), on the other hand, enables them back.

I guess that the MessageBox.Show handles events from the queue until there is a message that causes the msgbox to close, upon which the Show method finally returns the appropriate DialogResult value.

CLR Debugger confirms or at least doesn't contradicts my assumption. I attach a fragment of a stack trace from execution of the example. out.exe!Main._N__N_l64198062 identifies the function handling the tick event. Notice that the second call is in the control flow of the first.

out.exe!Main._N__N_l64198062(object _N_u1626 = {Interval = 5000}, System.EventArgs _N_u1627 = {System.EventArgs}) Line 12 + 0xc bytes Unknown
System.Windows.Forms.dll!System.Windows.Forms.Timer.OnTick(System.EventArgs e) + 0x17 bytes
System.Windows.Forms.dll!System.Windows.Forms.Timer.TimerNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x36 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 275, System.IntPtr wparam, System.IntPtr lparam) + 0x75 bytes
[Native to Managed Transition]
[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.MessageBox.ShowCore(System.Windows.Forms.IWin32Window owner = null, string text, string caption, System.Windows.Forms.MessageBoxButtons buttons, System.Windows.Forms.MessageBoxIcon icon, System.Windows.Forms.MessageBoxDefaultButton defaultButton, System.Windows.Forms.MessageBoxOptions options, bool showHelp) + 0x1f8 bytes
System.Windows.Forms.dll!System.Windows.Forms.MessageBox.Show(string text) + 0x26 bytes
out.exe!Main._N__N_l64198062(object _N_u1626 = {Interval = 5000}, System.EventArgs _N_u1627 = {System.EventArgs}) Line 12 + 0xc bytes Unknown

line used to compile the example
ncc -r timer.n