Goodbye Livejournal
I've decided to discontinue using Livejournal. The posts on this blog will remain up but future posts will appear on Google+.
Goodbye Livejournal
I've decided to discontinue using Livejournal. The posts on this blog will remain up but future posts will appear on Google+.
Initialisation dogma considered harmful
In C, variables aren't initialised to a value automatically. I've seen some people who seem to have adopted a rule of initialising every variable they use when they declare it. That is to say, they write code like this:
void frobnicate(void) { int num_frobs = 0; void *frobs = NULL; num_frobs = get_num_frobs(); frobs = malloc(num_frobs); ....
I think this is an actively harmful practise and should be discouraged. The reason I think this is that modern C compilers can detect when variables might be used without being initialised first (and gcc is scarily good at it), and adopting a rule like this of initialising everything breaks that functionality. Consider an example like this:
void clever_function_name(void) { mystruct *obj = NULL; int bar = 0; if (somecondition) { obj = new_mystruct(); bar = 1; } else { // oops, forgot to initialise obj here as well bar = 2; } ... obj->member = bar; }
I think the key thing is that initialising to a value like zero or NULL doesn't actually solve anything or prevent any bugs because it's just an arbitrary value. In a general sense, having a variable that is set to those values isn't any more helpful than having some random garbage that got left on the stack. It doesn't prevent uninitialised variable bugs, but it does prevent the compiler from detecting them.
How to coerce gdb into giving a backtrace
When debugging with gdb, I sometimes encounter a problem in getting it to recognise a stack trace. Sometimes it only gives a few function calls, or none at all. Here's an example:
(gdb) bt #0 0xb7886424 in __kernel_vsyscall () #1 0xb7559163 in ?? () from /lib/i686/cmov/libc.so.6 #2 0xb74f1387 in ?? () from /lib/i686/cmov/libc.so.6 Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) info registers eax 0xfffffe00 -512 ecx 0x80 128 edx 0x2 2 ebx 0xb75c33a0 -1218694240 esp 0xbfe55018 0xbfe55018 <= stack pointer on x86 ebp 0xbfe55048 0xbfe55048 esi 0x0 0 edi 0x0 0 eip 0xb7886424 0xb7886424 <__kernel_vsyscall+16> eflags 0x202 [ IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/64x $sp 0xbfe55018: 0xbfe55048 0x00000002 0x00000080 0xb7559163 0xbfe55028: 0xb75c33a0 0xb75c1ff4 0x09ec0470 0xb74f1387 0xbfe55038: 0xb77c4afd 0xb782199c 0xb782199c 0x09ec0478 0xbfe55048: 0xbfe55078 0xb77c4bf4 0x09ec0478 0xb782199c 0xbfe55058: 0x0000ffff 0xb75c3438 0xbfe55098 0xb789a240 0xbfe55068: 0x00000000 0xb782199c 0x0000ffff 0xb75c3438 0xbfe55078: 0xbfe55098 0xb7818736 0x09ec0478 0x00000000 0xbfe55088: 0xb77c50cd 0xb782199c 0xb7818709 0xb782199c 0xbfe55098: 0xbfe550b8 0xb77c54ad 0x00000000 0x00000000 0xbfe550a8: 0x0000000b 0xb75c3438 0xb77c5449 0xb782199c 0xbfe550b8: 0xbfe550c8 0xb77bb7dd 0xb782199c 0x0000000b 0xbfe550c8: 0xbfe550e8 0xb77bb84e 0x0000ffff 0xb789a240 0xbfe550d8: 0x00000000 0xb77bb830 0xb77bb839 0xb782199c 0xbfe550e8: 0xbfe55108 0xb77bc08f 0x0000000b 0x00000000 0xbfe550f8: 0x00000000 0x00000010 0xb75c1ff4 0x3efafafb 0xbfe55108: 0xbfe556c8 0xb7886400 0x0000000b 0x00000033
Pick a location slightly further up the stack and set the $sp variable, and suddenly backtrace works!
(gdb) set $sp=0xbfe55048 (gdb) bt #0 0xb7886424 in __kernel_vsyscall () #1 0xb782199c in ?? () from /usr/lib/libSDL-1.2.so.0 #2 0xb7818736 in ?? () from /usr/lib/libSDL-1.2.so.0 #3 0xb77c54ad in ?? () from /usr/lib/libSDL-1.2.so.0 #4 0xb77bb7dd in SDL_QuitSubSystem () from /usr/lib/libSDL-1.2.so.0 #5 0xb77bb84e in SDL_Quit () from /usr/lib/libSDL-1.2.so.0 #6 0xb77bc08f in ?? () from /usr/lib/libSDL-1.2.so.0 #7#8 0xb74ede80 in ?? () from /lib/i686/cmov/libc.so.6 #9 0xb74efc8c in malloc () from /lib/i686/cmov/libc.so.6 #10 0xb7764eec in ?? () from /usr/lib/libSDL_mixer-1.2.so.0 #11 0xb7765b98 in Mix_SetPanning () from /usr/lib/libSDL_mixer-1.2.so.0 #12 0x080828b1 in I_SDL_StartSound (id=-1218694088, channel=-1218699276, vol=120, sep=38) at i_sdlsound.c:671 #13 0x08073e9b in S_StartSound (origin_p=0xb624f990, sfx_id=22) at s_sound.c:656 #14 0x08061459 in T_MoveFloor (floor=0xb63271b8) at p_floor.c:220 #15 0x0806d0ea in P_RunThinkers () at p_tick.c:119 #16 0x0806d161 in P_Ticker () at p_tick.c:153 #17 0x08052fb6 in G_Ticker () at g_game.c:1151 #18 0x0804dbf4 in D_DoomLoop () at d_main.c:437 #19 0x0804ecc0 in D_DoomMain () at d_main.c:1506 #20 0x08054d1c in main (argc=5, argv=0xbfe55d04) at i_main.c:152
Most absurd CMOS battery ever?
I have a Performa 6400 PowerMac, which I bought off a friend several years ago. It runs Linux and I use it for portability testing (as it's a big endian machine). Considering its age, it's not surprising that the battery for the onboard clock ran out years ago. It's not a huge problem, but it's certainly annoying to have make complain about modification dates in the future, and be confronted with "filesystem has not been checked for 19370 days" on boot-up. So I decided to replace the battery.
This is the battery that is supposed to go in it. Almost £15 for a battery! This seemed far too expensive to me, so I set out to find an alternative. Unfortunately 4.5 volt batteries are rather uncommon. However, I managed to find this, which was listed as a "lantern battery" used for torches, bike lamps and doorbells. I suspect that there are probably 3 AA batteries inside:
- Greencell 312G 4.5V lantern battery alongside the original (depleted) CMOS battery.
I did a quick sanity check of the old battery to make sure I had the polarity right. The voltage is down to 1V:
All that needs to be done now is to connect the connector from the old battery to the new one. I've always been hopeless at soldering, but fortunately this is a job that is simple enough for sellotape.
This is the logic board from the Mac. I've maxed out the RAM and added PCI Ethernet and USB cards. The black square at the bottom left is where the battery is supposed to be attached (it has a velcro strip at the back).
Obviously this is far too small for the new battery, and the card slides into the back of the machine, mounted vertically. It has to be attached to the board somehow. Where can it go?
Fortunately, the engineers at Apple were apparently smart enough to anticipate this very problem, and designed a convenient space on the riser card to put the battery in.
Interview with me
fragorama.se is a new website about Classic Doom, and they have just published an interview with me!Southampton Test Hustings
I just attended the Hustings for Southampton Test. These are my thoughts on some of the candidates.
Alan Whitehead (incumber Labour MP): Seemed rather nervous at the start but gained confidence later in the debate. To his credit he made some good points; I was impressed that he was bold enough to state that the law of the land should trump religious beliefs. However I also got the impression that he was less up to speed with other candidates on local issues and perhaps hadn't been paying proper attention to his constituency. Surprisingly enough he opposes Trident in favour of a cruise missile system like the LibDems advocate.
Jeremy Moulton (Conservatives): Made some good points and seemed a confident speaker. Some of the answers he gave seemed to have been slighty evasive/misleading when audience members responded to his answers. Attacked Alan Whitehead for using the communications allowance and supposedly putting the Labour party name on it (?)
Dave Callaghan (Liberal Democrats): Seemed the most honest of the lot. He highlighted some of the local issues that he's been campaigning for, like the closure of the Millbrook library, which he attacked Jeremy on (Jeremy is responsible for finances on the local council?).
Pearline Hingston (UKIP): A UKIP candidate who is an immigrant (how's that for a brain-breaker?). She came across as completely clueless and in general contributed very little of note. The one time she really attempted to express an opinion on something (cyclists riding on the pavement) she got smacked down by a member of the audience in response for not having a clue what she was talking about.
Chris Bluemel (Green): Surprisingly clueful and well-spoken. He spoke out in favour of nuclear disarmament and did it well, even though I don't agree with his views.
During the debates I sat next to an older gentleman who spent the time scribbling down notes on the back of an envelope. When he asked a question to the panel, he made some strange comments about Halliburton and BP. He seemed to think that there were plans to site nuclear submarines in Southampton docks, and was worried they might blow up and destroy the city. Very odd.
There was an obvious large Christian presence in the audience, and I suspect that siting the debate in a church probably didn't help. The candidates were asked at one point why they had all refused to sign a petition (I forget the name of it) declaring their support for Christian beliefs, although it was then revealed that none of the candidates had even heard of it. Several questions were asked about Christian rights that were obviously homophobic (eg. anti-gay marriage), though the people posing the questions tried to veil this by speaking in vague terms that made it less obvious what they were talking about.
Chocolate Doom on OS X, and GNUstep
Chocolate Doom runs on Mac OS X and has done for several years; however, until now, getting it running has been overly complicated and required compiling the source code from scratch. Obviously this isn't really appropriate for a Mac; it certainly doesn't fit in with the Apple way of doing things. I recently set about trying to improve the situation.How about implementing parts of the Application Kit with GTK?
Yes and No - The GNUstep architecture provides a single, platform-independent, API for handling all aspects of GUI interaction (implemented in the gstep-gui library), with a backend architecture that permits you to have different display models (display postscript, X-windows, win32, berlin ...) while letting you use the same code for printing as for displaying. Use of GTK in the frontend gui library would remove some of those advantages without adding any.
How to make a program just run
Starting with Windows Vista, Windows limits the privileges that are given to normal users, running programs as the Administrator user only when necessary. To smooth over the fact that install programs for most software need to run as Administrator, it uses heuristics to detect whether a program is an installer. One of these is to look at the file name - if it contains "setup" in the name (among others), it is treated as an installer.
This is a problem if you develop a program that is not an installer but has "setup" in the name, because Windows treats it as though it is an installer and prompts you for administrator privileges.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <!-- The "name" field in this tag should be the same as the executable's name --> <assemblyIdentity version="0.0.0.0" processorArchitecture="X86" name="chocolate-setup.exe" type="win32"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> </assembly>
1 24 MOVEABLE PURE "setup-manifest.xml"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <!-- The "name" field in this tag should be the same as the executable's name --> <assemblyIdentity version="0.0.0.0" processorArchitecture="X86" name="chocolate-setup.exe" type="win32"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <!-- Stop the Program Compatibility Assistant appearing: --> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- 7 --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Vista --> </application> </compatibility> </assembly>
Python's braindamaged scoping rules
Python distinguishes between local and global variables from assignment statements. If a variable is assigned within a function, that variable is treated as a local variable. This means that you cannot do this:
my_var = None def set_my_var(): my_var = "hello world" set_my_var() print my_var
my_var = None def set_my_var(): global my_var my_var = "hello world" set_my_var() print my_var
New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.
Keep up with the latest Advogato features by reading the Advogato status blog.
If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!