GSSP-C

Note: This entry has been restored from old archives.

This is my somewhat long-winded reflection on the SANS GSSP-C certification. I signed up in September ’07, did the exam in London on December 5th, waited 8 weeks for my results, and eventually found out that I passed quite safely. The log below was written in parts, before taking the exam, then after taking the exam, then concluded once I got the results. It has been mixed up a little in the editing, but mostly retains this chronology.

The executive summary:

  • I passed, answering 84 of 100 questions correctly.
  • I barely studied, but I had read the “right book” previously.
  • I’m a security-aware developer in the infosec sector who works with C regularly.
  • I’m not convinced of the value of the certification to individuals.
  • But I think that it can be a valuable benchmark tool for large companies.
  • It worries me a lot that the “pass mark” is only 63.
  • Don’t get me wrong, I do think it’s generally a good thing – read on…

Guhsspeesee?

There’s just no amusing way to say, ‘I have a CISSP’.
MCSE is to computers as McDonalds Certified Chef is to fine cuisine.

If you’ve had any technical exposure to the ‘net it’s likely you’ve come across snide phrases like these (especially in witty email sigs if you’re on mailing lists of a security or Linuxy nature.) In certain groups these “qualifications” have little respect. But are they really as bad as all that? Is it a case of there being a few bad apples in the barrel damaging the reputation of the good MCSEs and CISSPs? The MCSE seems to be almost universally mocked. Maybe I just know the “wrong people”, though it isn’t all hearsay, I’ve had to deal with a couple of MCSE-holders who had less of a clue about kicking XP into shape than I did (and I don’t know much about Windows.) I can’t comment on CISSP at all from any personal exposure to the breed, it’s certainly popular in the IT business sector and certainly unpopular in more underground security circles.

Personally I’m not going to judge people by the acronyms they choose, often these things are a business or work necessity. That they choose to publish their acronyms in email signatures? Why not? Sitting an exam, regardless of merit, seems more worthy of note to me than most of the other crap people put down at the butt-end of their messages.

You can probably gather that I’ve never really been “into” these certifications myself. On average “my group” (covering a group of pretty hard-core C/C++ applications/systems/kernel developers) really doesn’t have much time or respect for them to there’s never been any motivation to take an interest. But I can’t say that every opinion I’ve heard comes with complete and logical justification.

From about mid 2007 SANS started pushing the “GIAC Secure Software Programmer” certification, the “GSSP”. This initially comes in two flavours: Java and C (but with plans for Perl, PHP, C++, … Befunge?) That’s where the “C” comes from. This is the first time I’ve seen a certification that seemed particularly relevant to my day to day work. I decided to give it a whirl, since there’s no other way to really know what to think about these things.

A Rant on the Philosophy

Going into this I wasn’t sure what to expect. How do you measure up a coder’s security abilities with 100 multiple choice questions? How do you wrap something as complex as “secure coding” in this format? On lists there has already been some discussion showing up regarding the merits of the new certification. The main non-troll argument is “you just can’t measure this with a multi-choice exam”. I think, as seems to be the main defence, that the definition of “this” is what needs looking at. The detractors seem to take the definition as of “this” as “l33t security dude“. On the other hand I think, in agreement with the defence, the certification is best seen as a filter to sort people with a clue from the totally clueless. The value? In the shoes of someone hiring it’s a nice measure that you don’t have a total newbie sitting in front of you. For larger companies I think it could be a good tool to discover where weaknesses lie in your developer farm. (So, like Hyenas to a sick Zebra, your HR people can cull the weak! No, really: so you can properly target training and awareness programmes.)

Alas there is some marketing and up-speaking from SANS that does paint a little bit of a “silver bullet” picture around the certification. It’s easy to see where the detractors get their iffy feeling about the whole thing. Remember that SANS/GIAC aren’t charities, they have to sell this idea — and in this situation a little of the technical reality is lost to marketing drive.

I think this push has the potential to significantly weaken the value of the GSSP, “certify your coders and you’ve solved your security issues”. Having coders who can pass a test and who’re aware of bad practices is different from having coders who’re contentious in the application of their knowledge. It isn’t a replacement for peer reviews, regular code audits, code ownership, and plain old responsibility! I think that there is strength in the GSSP if viewed as one part of a more holistic approach to creating secure software. Don’t push it on your developers as yet another management hurdle shoehorned into their schedule! The last thing you want to do is say: “We’re hiring this expensive contractor in a suit you’ll talk at you for an hour every Friday for the next month, then you’ll take an exam. If you don’t pass your exam you’ll get a smaller bonus.” Yes, companies actually do do this, I’ve seen the insanity first-hand.

Is there an alternative? There must be! Start by getting actual developers behind the scheme, not some outsider in a suit. I could keep going on my thoughts here, but maybe another time. The point, as relevant to this entry, is these are my thoughts in the couple of months thinking about this before taking the exam. (In fact, in bulk, actually written prior to sitting the exam.) I wasn’t going into this as a fanboy, as usual my scepticism runs high.

Practicalities Prior to the Exam

The obvious starting points are the handbook that enumerates the exam content and (if still up) the webcast. The webcast is particularly useful as it involves Robert Seacord who’s one of the heads behind the exam and responsible for a highly relevant book on the topic. The ‘cast covers the sections you’ll find in the exam, the content, and the topic weightings.

The content of the blueprint seemed straightforward, the everyday issues that any C developer should be thinking of. I resolved not to worry much about study since it would be most interesting to see how I’d “rate” just going into this thing and giving it my best shot. So, in essence, my pre-exam “practicalities” were minimal. Just like in my Uni days, study is something for other people to fret about. (I don’t claim this is a good philosophy!)
Claiming a total lack of study would be dishonest, a few months ago I read Robert Seacord’s Secure Coding in C And C++.

Through several weeks of morning coffees I gradually made my way through this volume, it’s a good size for a morning-espresso(s) book. The content is a little dry, so it took a while to get through despite being fairly short (early in the morning it can seem far more profitable to stare into your espresso than to read about buffer overflows!) This is particularly relevant to the exam given the author’s involvement with the GSSP, and it turns out there is a strong symmetry between the content of his book and the topics enumerated in the GSSP-C handbook. So in a vague and fortuitous sort of way I’d covered some study content. For potential studiers it is a good starting point, but not all details covered in the exam are covered in this one book.

I can’t comment on the other books recommended on the SANS site as I’ve read none of them. On the website front one stands out, the CERT Secure Coding Initiative and especially the related Secure Coding standards web site. The latter is a wiki aimed at developing a secure coding standard. The content of the wiki covers much of the GSSP-C exam blueprint, in fact one of the major contributors is Robert Seacord. (You’ll see a prominent advertisement for his book in the sidebar.)

My Qualifications

So minimal study hey? What are my “qualifications” going into this exam then, what sort of person is being tested here?

I “learnt” C in around 2nd year of Uni, though IIRC none of the courses I took ever taught C specifically (we had a 2nd year C++ course). That was about 7 years ago. Through Uni I played with C a lot, mostly through an interest in some Linux systems and applications. Before completing Uni I also taught practical classes in “Programming Practice” to 2nd years, that was all in C (what a nightmare!), I learnt a lot of little details then to keep ahead of the syllabus.

Since Uni, as a developer, I’ve coded in C fairly often but not in a continuous or hard-core sense. I’ve used C++ and Python more often, but in the months leading up to the exam was mostly dealing with plain C. I also spend a fair bit of time auditing C code and working with/in 3rd party code, which is often pretty terrible. The context of this work has been that of being a development/research/integration(/pre-sales shudder) engineer for a startup/research/OEM company in the network security sector for several years (approaching 5.)

In essence, I consider myself a competent and security-aware C coder who still has a lot to learn. Neither a security expert or a C expert though, in my opinion expert is a pretty strong word.

The Big Day

So on Wednesday December 5th, just before 9AM, I walk into a room at the EcXeL centre in London. I wasn’t sure what to expect, being at a huge convention centre I was thinking it’d be a uni-eqsue exam situation, a huge cold room with a couple of hundred people sitting at little desks. I figured there’d be a pile of finance sector wage-slaves sucked into the process by this time. But the bandwagon, if it is to become such, had only just started rolling — this was the first exam held in Europe after all. I expect the big corporates will have their own in-house sessions arranged anyway. I walked into a room where only 12 people would be sitting an exam, and, if I counted right, just 5 of them were there for the C. The others doing the Java version, but that’s no surprise since there’s a pretty high demand for Java people in the City.

Of the exam content itself there isn’t much I’ll say as, logically, you agree to an NDA as part of taking it. Don’t worry about it branching out horribly from the “blueprint” in the handbook, it didn’t. You might want to worry a little that some questions lean a little towards the qualitative, rather than quantitative, side. But this might merely be the delineation between a good secure coder and someone who can merely recognise instances of bad practice. Given an example with multiple flaws, all of which make you shudder, which flaw is the worst? I had some difficulty with some of these and similar questions that required rankings of flaws and solutions, and classification of flaws. There were also a couple of questions that essentially required knowledge of security “glossary terms”, this is one area where a bit reading up on things in the suggested references is really going to help (I winged it as best I could since the terms tend to be fairly self explanatory.)

Reflecting on the Exam

Just going through the questions was worthwhile in a couple of ways. First, it highlighted some small gaps in my knowledge right away when either a question completely stumped me or I saw something and realised I didn’t really know what should happen with any certainty. Second, I recognised my strong reliance on manpages, I simply don’t commit much detail to memory when it is always handy the ubiquitous “dev” manpages. Over years, gaining more C coding experience, I imagine the manpage reliance will diminish. But anyway, you’re unlikely to find yourself working without manpages — so long as you don’t go making assumptions surely you’re OK?

Other gaps include: “terminology” and “severity”. The former is just knowing the right collection of glossary terms, best gained through more reading I supposed. The latter is a bit of a funny one, when presented with code containing several of the worst mistakes a coder can make I think “this code is crap, it’s all bad”. But you’re asked to pick the most severe flaw. Which one is it? The one that, in the right circumstances, could give an attacker arbitrary-code execution? The one that can reliably make the program crash (DoS) 100% of the time with the right input? I can’t answer these ones comfortably, as far as I’m concerned all the flaws are bugs that must be removed, none are acceptable.

It does seem they had some trouble coming up with their 100 questions as there was quite a lot of repetition and a few questions that felt like “filler.” I assume they need a corpus much larger than 100 in order to randomise the exam content between sittings.

The Results

“Results will be sent in the post 6 weeks after the exam. Results will not be made available over the phone or Internet.”

Waiting, waiting, waiting… Given it was filled in on one of those machine-marked sheets I’m surprised there’s a six week waiting time. Especially surprised that I didn’t get the results until more than 8 weeks later. The whole Christmas/NY thing was in the middle though, so I guess we can write off two weeks. But even then it seems a long time to deal with less than 20 exams.

The results arrive in an envelope with SANS on the front and even a real stamp from the USA. I know what it is right away and eagerly tear it open right away, “Congratulations!” is says. “Ah,” I think, “so I didn’t totally waste my 200 quid.” The letter is short and to the point, I passed the exam and a certificate “will follow under separate cover.” Whatever that means, I assume the translation is “in a separate envelope.”

SANS GSSP-C Letter
SANS GSSP-C Letter

The envelope also includes a separate sheet with your final results and summary of how you performed in the different parts of the exam. In the end I got 84 questions right, I guess you could call that 84%. It turns out that the “passing point” is 63, so I passed pretty safely. Looking down the breakout there’s no one area where I did particularly badly, and also none where I answered all questions correctly.

Section    Mark    Out Of
Secure interaction with environment 21 23
Resource management 17 28
Filesystem IO 10 13
Employment of specific security measures 8 10
Concurrency 5 6
Understanding data-types 11 15
Handling error conditions 4 6
Code correctness and style 8 9
TOTAL 84 100

So, that’s it. Passed.

Personally I think getting 16 questions wrong is pretty bad. “Secure coding” is mostly rather black and white, getting things wrong at all is insecure coding. I have to admit that it kind of scares me that the pass threshold is 63! That means that someone can be 37% insecure and still pass. In other words, people getting this certification could be more than twice as insecure as I am.

Is is Worth It?

Too early to tell really. I got a couple of good things out of doing the exam: I noticed some gaps in my knowledge of what it was testing, and I found out what sort of barrier the exam sets. Whether it “furthers my career” in any tangible way is going to be hard to measure (just like measuring “secure coding”!) It probably won’t make much difference, since most places I’m likely to work will be pretty “geek” (so possibly fairly dismissive of “certifications.”)

Is it worth US$499? Maybe not to the individual, unless it becomes wide-spread for companies to require this qualification for new hires I don’t think it matters much. On a CV, going into the right sort of job, it probably makes for a reasonably good differentiator. (Or may mean nothing, depends on the sort of shop you’re applying for — I know of people in security who’ll filter people out if they seem to make a big thing of having a CISSP.) As far as judging the value goes, I’m a “special case” — I place a high value on satisfaction of curiosity and doing this exam did that for me (I’d probably have to give myself a good slap for not taking study seriously if I’d not passed though.) I also think there’s value in it having highlighted a few things that I didn’t know, but, as the results above attest, I don’t seem to be missing any whole zones of knowledge. It would be nice to know more about the questions I answered incorrectly, since otherwise it is hard to pick up on what I might need to research to bridge the gaps. Anyway, it helps that the GBP is nice and strong against the USD!

If one thing concerns me above all else it is that 63% pass mark. I seriously don’t think that someone getting 37 questions wrong should be considered a “secure software programmer.” In fact, I’d be more comfortable with an 85% cut-off (which would rule me out, so maybe 80%.) As an employer, if someone was talking up their GSSP-C I’d want to see their itemised results before giving much weight to it. Given my experience from taking the exam I’d consider a mark of 70 to be pretty borderline, but I’d consider it a good starting point for someone in a more junior C development role. (Update: 2008-04-08: My name is finally on the list, along with 18 others at this point in time. A rather short list! It’d be interesting to know how many people have sat the exam. Of the 19 “analysts” at this time, 4 people scored higher than me, one with 85 and three with 86.)

I think that the GSSP-C can have a much higher value to a large company wanting to gauge the abilities of its herd of coders. I imagine that if you’re pushing 100 people through the certification you’d get a discount!

It seems a little funny that they’re going to have a different exam for the GSSP-C++ … while there are some C++ specific security concerns most issues are the same as for C (no surprise, right?) It smells a little like milking the “secure programmer certification” for all the $$$ they can get. I’m a cynical bastard. I’m far from the first person to be critical about the GSSP though, in fact SANS SSI has a page devoted to critics, and I’m glad of that. The existence of that page makes me more confident in the certification and the process that gave birth to it. Though it was last updated in April 2007, I’m sure there must have been more critical feedback since then! (Note also that the page covers the C/C++ split and discusses why it was split and the related difficulties.) It’s also clear that the technical people behind this test, and SANS in general, are serious, concerned security professionals. If anything we can hope that the existence of things like the GSSP will raise awareness of secure programming methods and give the world more such professionals.

Got Milk?

Note: This entry has been restored from old archives.

I think I’ve found the best supermarket milk in the UK: Duchy originals organic freshly pasteurised Ayreshire milk. It tastes brilliant and, as it isn’t homogenised, comes with a little dollop of creamy goodness under the cap (probably containing 10% of the calories in the bottle!) Even the semi-skimmed product is pretty decent. All thanks to good old prince Charles.

Mentioning semi-skimmed brings another thing to mind: public health awareness as a function of corporate marketing[1]. Low fat anyone? Low salt? Low GI? Maybe it’ll be low pumpernickel next? Before you reach for the semi-skimmed take note that typically the Calorie difference is only about 25%. There really isn’t any point unless you drink litres of the stuff per day. A cup of the full-cream milk I have in front of me contains 160 calories, the semi-skimmed alternative would contain no more than 40 Calories less. That’s right, just forty. Taken in the context of a standard male adult intake of 2500 Calories the difference is a mere 1.6% (2.0 for the adult females.) Of course, for many, the “standards” are usually way off the mark (exactly how average are you?), in the context of my current calorie intake at 15% below BMR (~1650 Cals) this is still only a 2.5% difference! If I can fit normal milk into my diet then anyone should be able to!

The conclusion? Dump the bloody skim milk, it doesn’t taste good and makes stuff all difference anyway.

What about the fully skim-milk you ask? Well, you may as well stick to water in my opinion. But that aside, skim milk is typically 50% lower calorie than the full-fat cow juice, yet even then for a whole 250ml of the stuff we’re talking less then 5% of your daily Calorie intake. A quarter litre is a fair bit of milk too and, unless you guzzle glasses of the stuff straight, you probably have less than that per day taking into account normal sized servings of cereal and tea/coffee (I shudder to mention having milk in either though.)

Want some advice? Keep a closer eye on the sugar and other carbs in your breakfast and drinks. That low-fat chocolate milk drink from the inconvenience store would be fine if it didn’t have twice as many Calories in sugar than it has left out in fat.

Anyway, the point was: HRH Prince Charles sells good cow-juice.


[1] Something I’m not going to delve into in great depth. One of the wake-up moments for me, that made me take a closer look at just about every piece of “accepted knowledge” I came across, was coming to the UK and finding “non-bio” prominently displayed on many laundry detergent products. I had no idea at all what this meant! It turns out that at some point in the distant past there was some big scare about “biological” (containing enzymes) detergents causing drastic eczema and even toxic-shock, so everybody avoids the stuff. Meanwhile, back in Oz, companies market “enzymes” as a great thing for your washing powder (and I hear things are much the same in the US.) In the end it is all a function of marketing, this “fact” came up, some company pushed it into their marketing campaign, and everyone jumped on the bandwagon. Fat? Think of the billions made on marked up low-fat (usually high sugar) products, the English-speaking-worldwide anti-fat campaign has been around for decades yet this world gets more and more obese by the day. Eggs? Salt? Red meat? So many “evil” foods of this day and age have their original evilness based on flawed studies (some as long ago as the 1960s!) The great news is that more recent research is countering many of the earlier studies. Not enough salt will kill you, no saturated fat stuffs with your hormonal system, cholesterol from eggs is good for you. It’s all terribly frustrating, how do we know what to believe? I wish I knew. My best guess is keep things balanced. Almost always eat “rough” foods (i.e. stay away from things with more than three flow-chart states between their origin and your table: killed->packaged->cooked), and get a good share of calories from protein and fat (about 40% and 30% in my case). I’d say it is pretty clear that the government and industry backed low-fat-high-carb diet has failed. My, that turned into a rant didn’t it?

boost::bind and <unresolved overloaded function type>

Note: This entry has been restored from old archives.

I had a hard time Googling a solution to this particular woe. Alas the exact string “unresolved overloaded function type” doesn’t give anything useful with “boost::bind” and “boost:mem_fn“. This is the typical sort error message from g++:

foo.cpp:18: error: no matching function for call to
    'bind(<unresolved overloaded function type>,
        const boost::reference_wrapper<FooMaster>, boost::arg<1> (&)())'

I’ve generated this using a rather contrived example based on the use pattern that was causing my woe:

#include <iostream>
#include <boost/bind.hpp>

class FooMaster {
public:
    void foo(std::string &s) {
        std::cout << "foo(s=" << s << ")" << std::endl;
    }

    void foo(int x) {
        std::cout << "foo(x=" << x << ")" << std::endl;
    }
};  
    
int main(int argc, char **argv) {
    FooMaster fm;
    boost::bind(&FooMaster::foo, boost::ref(fm), _1)(10);
    return 0;
}

The problem is obvious of course, it is exactly as the compiler is telling you. Mr compiler has no idea which “foo” you’re talking about. “But Mr Compiler, it is obvious!” You say. “I’m not passing it a bloody string!” Sometimes you just have to understand that Mr Compiler isn’t you and needs a little hand-holding.

The issue clearly boils down to FooMaster having two methods that match &FooMaster::foo. This signature, used to instantiate the bind template, doesn’t take into account the arguments, so which foo are we taling about?! Alas, as obvious as the problem was I didn’t find the solution so obvious. I just don’t cut it as a C++ guy sometimes. I’d given up on the problem in fact, but then I stumbled on a solution while looking into some other problem I had. It was one of those “oh, duh!” moments really, I was looking at some code that assigned a member function pointer. The type specification for such a thing includes the argument types! So here’s a modified main that uses one extra step in order to explain what we want to the compiler:

int main(int argc, char **argv) {
    FooMaster fm;
    // Create a variable of the desired function signature type and assign
    // using desired member function.  This will resolve the correct
    // function thanks to the signature including the argument types.
    void (FooMaster::*fn)(int) = &FooMaster::foo;
    // Now pass the function variable to the template method so that it knows
    // exactly which function we mean.
    boost::bind(fn, boost::ref(fm), _1)(10);
    return 0;
}

All you have to do is give Mr Compiler a little bit of a helping hand…

Joy!

Firefox Slowness Redux

Note: This entry has been restored from old archives.

While I did get around to my one-extention-at-a-time testing of Firefox slowness I still haven’t got around to writing more about it. My, rough, observations are the following:

  1. The longer Firefox is running the slower everything gets. As much as I’d love to turn my computer off every night and start afresh every morning the fact is that the best I can do really is put it into suspend, without wasting time every morning (I work at home and maintain a lot of state on my computer.) Another solution would be to stop-start firefox every now and then since it’ll reload my last set of open tabs/windows on starting, I really shouldn’t have to do that though, and it leads to point 2…
  2. More tabs seems to mean more slowness. I tend to be tab-happy, like my 20-desktop(+tabs) spaces of state I find keeping stuff open in the browser to be simpler than worrying about “saving tabsets” and bookmarking everything (and trying to work out one end of the “history” from the other is just not going to work.) To this end I tend to have 2 or three browser windows open at a time with up to three rows of tabs in each. The slowness isn’t Firefox hitting swap so must be something else (Firefox memory use seems to grow linearly with number of tabs open, fair enough I guess since memory is cheap these days.) Maybe a plugin or extension, I haven’t tried the incremental-plugin/extension-addition + tab-growth experiment.
  3. The “SwitchProxy Tool” extension does seem to cause slowness. I’m confounded as to why it should be so!
  4. The “Google Browser Sync” extension also causes slowness. Again, I have no idea why, but it does a pretty complicated job.

That’s all I have to report. And AFAIC “problem solved!” “How so?!” You ask? Simple: I’ve mostly stopped using Firefox. Over the last few weeks I’ve been making a gradual switch to Opera. Oh no! It’s closed-source evilware! shrug It is:

  1. Faster (oh, so much faster!), more responsive when I have 50 tabs open in three windows.
  2. No longer encumbered with that annoying ad panel.
  3. Now equipped (in the current beta) with native browser-sync functionality. This is nice since Google Browser Sync has become, for me, the most important Firefox feature. That said, I don’t know how “trusted” the Opera browser sync is and it certainly doesn’t seem to be as comprehensive as the Google offering. I expect Opera sync will be expanded in time.
  4. No more of a memory hog than Firefox (as far as I can see, but I haven’t tested this exhaustively.)
  5. Binary packaged for every distro I use and there’s an apt repository (though without Ubuntu dists, my sources.list line on Ubuntu gutsy is for Debian testing.)

On the downsides:

  1. Has occasional problems with Flash, which require a browser restart but luckily Opera comes back up with all my windows and tabs rather quickly. Yes, in an ideal world there’d be no flash, wank, wank. Flash is a “fact of life” as far as the web goes these days, and IMO it gives us some useful things that would XHTML/CSS can’t. This particular problem is my most pressing issue with Opera at the moment.
  2. No less of a memory hog than Firefox. This is based on occasional glances at top while running both, not any proper testing!
  3. Much less of a CPU hog than Firefox but still pretty bad at idle sometimes. However this is mostly the fault of websites to some degree, it just seems that Opera keeps a tighter hold on not letting a site’s javascript get out of hand. For example, having smh.com.au open in Firefox really bogs it down, while Opera remains responsive (albeit at a constant ~10% CPU usage on my desktop.) It should be noted that the smh.com.au site runs some particularly disgusting javascript.
  4. Hitting sites that “don’t work in Opera” is more common than “don’t work in Firefox”, but the Web’s become pretty good in this regard these days so this is fairly rare.

It should be noted that I’m using a beta version of Opera (on Ubuntu Gutsy.)

There are things I haven’t tried or worked out with Opera yet. Namely:

  1. What’s on offer as far as equivalents to the Firebug and Web Developer Firefox extensions. I haven’t had to do any HTML/CSS debugging for a while.
  2. AdBlock Plus equivalent? I think there might be one out there, but I have to admit I’m not hunting since I’ve kind of fallen out of love with auto-updated ad blocking, it was blocking things I wanted to see sometimes. Opera does have a “content block” feature and I use it to block out particularly bad ads and ad-iframes (anything I see that is large, or overtly bright, or animated.)

I haven’t spent much time looking into equivalent Opera functionality as I have everything I need for day-to-day browsing “out of the box.” However, I just found “Opera equivalents to Firefox extensions” and “Opera equivalents to Firefox extensions II” which look like a pretty good starting point!

In conclusion: I’m converted to Opera. It has it’s downsides, but so does Firefox and my feeling at the moment is that Firefox is more annoying than Opera.

Avruga Caviar

Note: This entry has been restored from old archives.

In my recent review of Coq d’Argent I mentioned Avruga Caviar. This topped off the timable that was part of Kat’s froggy entrée. I also referred to it as “damn good”, and it was! However, I should make the point that it does not seem to be actual roe… rather, some recombined smoked herring meat product.

When I wrote the Coq entry I assumed two facts: 1) That the caviar was herring roe, and 2) that “Avruga” was a generic term for herring roe caviar. The process whereby I unravelled these facts has been interesting, albeit a little bit of a waste of time.

Internet (Mis)Information

It all started with my Coq entry, I Googled “Avruga caviar” so I could link it from my review. I found two reasonable looking sources, one was on Wikipedia, a two sentence entry that said Avruga “is made from the roe of herring” (emphasis mine.) The second was on a site called iGreens.org.uk, which states that Avruga is “made from the roe of the common herring.” So I went ahead with this information.

Culinary Interest

The iGreens site said that Avruga was “Available from Waitrose, selected Sainsbury’s and Tesco’s.” Armed with this knowledge and an interest in getting better acquainted with Avruga I wandered up to Waitrose to get some bits and pieces for an evil cold platter for dinner. Alas, no Avruga! Instead I got a “herring caviar” named “Onuga®” in the hope that it’d be similar. We had a nice evil dinner of figs (argh! the “food miles!”), goats cheese, olives, and Onuga on spelt crackers. Washed down nicely with a 10yo tawny port. FYI: We do not normally eat this sort of food!

Before dinner I set about some Google sleuthing to see if “Onuga” was “Avruga” and find out more information about herring roe caviar.

Avruga® Revealed

In time I tracked down an official product page for Avruga to discover that the word Avruga requires a registered trademark symbol. Avruga® is the name of a product marketed by a Spanish company called Pescaviar. Along the way I also discovered that it is produced for Pescaviar by a company called Cataliment (no online info) and has Marine Stewardship Council “Chain of Custody” certification. This latter information comes from the news page of a website belonging to marine fishery consultants MacAlister Elliott and Partners.

So not only is it great “caviar”, it also takes the pressure off the poor old sturgeon and has impeccable environmental credentials. Eating this stuff should give hippies orgasms.

Spreading The Word

Armed with my new-found knowledge I trundled off to update the Wikipedia article. Aiming to clarify that “Avruga” was a product name and expand the snippet with the information about the producer and environmental certification.

This is the first time I’ve edited a Wikipedia article and doing so is an interesting insight on how the whole Wikipedia process can work. You just need enough enthusiasts who can’t get their priorities straight (I’ve really got other things I should be doing), Wikipedia has a whole Internet full time wasting nutjobs like myself.

After making some edits I discovered things like it being useful to review the “history” and to add update comments (I didn’t even see the form field for this when editing the entry.) Anyway, in the history I saw “Clarified the fact that it is not fish roe” followed by “Avruga caviar is made from herring meat not the roe? What utter garbage. I ate some avruga caviar tonight at a restaurant. It is ROE. Corrected article accordingly.”.

I was intrigued.

Reformed Herring

When someone makes such a pompous sounding “statement of fact” with no backup I get edgy. I’ve done it myself so many times and had it end in an embarrassing counter-proof almost as many times. The other thought is: why would someone bother to say it isn’t roe without some good reason? Since it is certainly seems to be roe.

The first thing I did was take a look at my jar of Onuga. The line “reformed herring product” was suspicious, if strangely worded. Reformed, like reform school? The ingredients revealed that the main contents were “water” and “smoked herring”, no mention of roe? I’m pretty certain that if it was roe it would say so!

But Onuga is not Avruga! On a closer look at the Avruga product page I noticed the phrase “Pescaviar has developped[sic], from wild herring, a unique product” and no mention of anything like “roe” or “eggs.” And re-reading the MacAlister Elliott page revealed the phrase “faux caviar.” I also did a Google image search to try and spot the ingredients list on the jar, in the fuzzy edge of one image I saw “smoked herring”.

I dug a little deeper and found the references to Pescaviar and Cataliment on the Marine Stewardship Council’s “PFA North Sea herring” certifications page. Both entries are for “smoked”. Adding this up with the information from the MacAlister Elliott site starts to make it sounds like much the same thing as the Onuga caviar.

I don’t claim any of these things as proof, but I’m certainly feeling convinced.

Who Cares?

I made another update to the Wikipedia article on Avruga caviar to include my new observations in as much of a “wikipedian” manner as I could. It’s hard work avoiding “weasel words.” Then again, the original article cited no sources as all, if I knew the markup for it I’d tag “has seen Avruga quickly gain popularity” with “citation required”. It seems feasible, but I’d like more information to back that up.

What does this mean for Avruga? I have to admit that the concept of caviar has a certain exclusive air to it and that the idea of “reformed” fish meat “caviar” feels like a cheapening of this. However, we need to be realistic about these things! Get off whatever try-hard, wannabe, foodie high-horse you’re on and just enjoy it. Call it tiny balls of firm fish jelly if you like.

The Onuga was good, firm little balls with a mild fishiness. Was it “good caviar?” It didn’t have the crispness and “burst” of real caviar, for sure, and Kat and I would go salmon caviar by preference without hesitation. I don’t think the Onuga was as good as the Avruga either. But without a side-by-side test it is hard to say, enjoyment of food is physiologically and psychologically complex. There are many influencers; in this case accompaniments, environment, and perceived value come to mind immediately. The Avruga would have also lacked “burst” I assume, so certainly requires revisiting without the trappings of a “high class” restaurant meal. Also, I only had maybe 5 or 6 little balls of Avruga and didn’t give them my full attention, since it was Kat’s entrée. It certainly wasn’t bad, we did come away from it thinking “damn good,” after all.

Gah! I’ve got to try and get my priorities straight! I thought train-spotting geeks were bad… here I am spending 3 hours worrying about faux caviar! I’d better put my jellified smoked herring balls back into the fridge and go to bed.

Coq d’Argent

Note: This entry has been restored from old archives.

It was that time again, time to go out to a great restaurant as a “make up” dinner because I’d had to bugger off somewhere and leave Kat alone a for a week. Such creatures become unhappy when left to fend for themselves for too long. Exactly where to eat is always the problem, there are so many interesting restaurants in London. I juggled around a few names I remembered and tried to find somewhere that definitely had Squirrel on the menu at the moment, but no luck there. So, something different at least? We normally do very Italian style food so how about French? A couple of names came to mind and on the back of seeing a lot of good reviews it was Coq d’Argent we chose.

Coq d’Argent can be found on the roof of N° 1 Poultry, convenient for “City” folk (like Kat, who works only a 2 minute wander down the road.) Poultry/Coq is just the first witty pun. “Argent”, it seems, can be taken in two meanings: one being “money” (we’re in the banking district after all), and the other, from heraldry, “silver” (pretty much the same link to the City there I guess). So, the “Silver Rooster” on N° 1 Poultry in the financial district. Ho ho. Anyway, enough randomness, we’re in this for the food.

Entrée

Coq is a very French restaurant, complete with all the stereotypical French dishes. This left me with a bit of a conundrum when it can to the entrée, only two?! So we picked three. Kat had the cuisses de grenouille, which is frog’s legs to you and me. While I ordered the terrine de foie gras au jambon fumé, which doesn’t need translation I think! Then to share we had another dish that really speaks for its self: douzaine d’escargots.

Frogs legs, foie gras, and snails— could we try any harder?

Timbale de cuisses de grenouille au vermouth, Avruga caviar et crème d’épinards.
(Frog legs and vermouth timbale with spinach cream and Avruga caviar.)
The timbale came with an escort of three little legs, nuggets of meat in a very light crispy batter complete with little bones sticking out. The legs were succulent and, I guess, a little like dark-meat on chicken. The timbale was delicately flavoured, so as to not overwhelm the leg meat it contained. The spinach cream (or: creamed spinach) and caviar topped off the whole dish well. Avruga caviar is actually a fancy name for a caviar made with herring roe, and my assessment of it was that it was rather good! (However have a look at that link to learn about the true nature of this “caviar”.)

Terrine de foie gras au jambon fumé, poire aigre-doux, purée de pruneaux.
(Foie gras and smoked ham terrine, pickled pears, prune compote and sherry vinegar caramel.)
Ah, foie gras, I don’t know how much the goose suffered but it was all worth it. A good rich terrine this and a reasonably sized slice (for this day and age.) The “pickled pears” barely rated a mention, coming in about 10 pieces about 3mm to a side. Personally, I’d have preferred a few neat slices. That said, they’re really just there to lead some sharpness to cut the thick richosity of the terrine and the prune compote came in a good dollop alongside a drizzle of the “vinegar caramel” (think darkened sugar syrup) that lent it’s own edge. I enjoyed every mouthful, even the ones Kat ate.

Douzaine d’escargots de Bourgogne au beurre d’ail et tomates.
(Twelve snails baked in garlic and tomato butter.)
Straight out of the French language textbook! (I studied French for three years in school, but somehow didn’t learn a thing.) There’s always the snail horror stories you hear: “chewy little lumps of garlic flavoured rubber.” I’m glad to say we didn’t have such an experience, the dark little bodies of our snails, tucked delicately into their shells, were succulent and melt-in-the mouth tender. I’m not sure what to compare them to actually. And you can’t go wrong with garlicy butter, especially when there’s bread nearby.

Main Course

That wraps up the first course, and what a beginning! I’d had some difficulty choosing my main course and ordering three really wasn’t going to be an option. Wanting something with a bit of meat to it I went for the filet de sanglier, wild boar. Kat eyed the fish for a while before actually choosing agneau rôti à la provençale which was actually agneau de pré-salé, or salt-marsh lamb. This, despite the “salt” and related seaside environment, really isn’t quite fish. Right after the entrée I popped along to the bathroom and found the mains already on the table when I returned! A tad too speedy for my tastes I have to say, it must have been less than ten minutes between clearing firsts and laying out the seconds. Agneau rôti à la provençale, jus au romarin.
(Salt marsh lamb with mini ratatouille, soft mash, pesto, anchovy fritter, black olives and rosemary jus.)
Kat’s main was a sizable serving, with three decent pieces of lamb (including a cutlet). The presentation was an amusing construction whereby an encircling wall of mash, dotted with olives and pesto, had been built around the core constituents of the dish and filled with a shallow pool of jus. That was the pinnacle of presentation for the evening, though every dish came with a strong dose of the art. (Something I have only a marginal respect for.) I found the anchovy fritter an unusual and maybe too cheffy device, essentially packaging for a condiment. However, this was a good solid dish and the lamb pink and juicy. This “salt marsh” lamb is talked up a lot but from the little I tasted and from Kat’s words I don’t think we recognised anything really special about this lamb. Don’t get me wrong though, it was very good lamb, I’m just not sure if it was amazingly, wonderfully good. I will have to endeavour to get myself a leg or shoulder of it for a more complete assessment.

Filet de sanglier sauce grand veneur, purée de marron et panais rôti.
(Wild boar fillet wrapped in pancetta with chestnut purée, roasted parsnip and grand veneur sauce.)
Three small medallions of fillet made this a much less substantial meal that Kat’s, but sufficient. Being served with one tiny, lonely baked onion (it’s not listed, so it’s a bonus I guess), and a couple of skinny sticks of parsnip certainly doesn’t bulk it out enough for those who measure enjoyment by volume! A good thing I fit less in and have a smaller appetite these days then! The chestnut purée was an excellent wetting agent for the plate, not something I’ve had before but something I’ve got to add to my repertoire. Now the sauce is a bit of an enigma, I tasted it and immediately recognised chocolate and Kat agrees. If I’d thought to review the menu and seen “grand veneur” I’d have asked about it, but Kat said she saw mention of chocolate on the menu and I left it at that. The problem is that the online menu (which I used as reference for the names in this entry) says it is a grand veneur sauce. This is, essentially, a rather complicated stock reduction (a poivrade) thickened with blood and finished with redcurrant jelly and cream. There was certainly no hint of anything cream-like in the sauce with my meal! I suspect the answer to this puzzle is that the menu of the night was slightly different to what they have online, which is a fairly common occurrence (restaurant menus tend to be “live” documents.)

OK, I’ve written far too much about this dish now and not even approached the point yet… how was it? Good, the possibly-chocolate sauce and chestnut purée were a highlight and I’ve got to keep them in mind when I tackle game meats in future. But not brilliant, the “wild boar” lacked the sort of strong flavour I hoped for and what flavour it had was hard to find behind the flavour absorbed from the pancetta. Aside from my persnicketiness in regard to flavours the dish added up to something enjoyable, the boar tender and the sauces unusual and flavourful (maybe a little sweet, there I go again.)

Along with our mains we had a small rocket and parmesan salad, dressed with a good balsamico and, refershingly, lemon juice. The acidity in the salad worked well complimenting the flavours in my main.

Dessert

There was certainly room for dessert! Given the non-overzealous serving sizes, the small amount of bread (a good thing), and our choice to order only a very small salad as an extra. Kat went straight for the Catalan crème brûlée, which was an excellent and very rich rendition of this all time favourite. I debated whether or not to have one with poached rhubarb or something much richer and chocolaty. I don’t normally go for chocolate desserts so decided to give it a go for a change and had the “Warm bitter chocolate and marmalade sabayon tart with orange ice sorbet.” It beat Kat’s dessert on richness, twice over at least! The tart filling was akin to a warm version of my richest chocolate mousse and the crust thin and crumbly, this balanced very well with the frigid tang of the sorbet. If anything the tart could have been just a little smaller.

The Rest

I didn’t have any wine with this meal, sticking to just water. I was glad to note that their still water was UK sourced and not imported from some ridiculous location. It was also supposedly “carbon neutral”, however they work that out. I almost always stick to tap water these days, water from Fiji? People are idiots. Anyway, the water was good and a little less uncomfortable.

Kat had a glass of Chianti, it was very good, you’d hope so at £11.50 for 125ml.

We dared espresso, and that was nothing special. I don’t really like espresso in France (based only on experience in Provence and Corsica) but it is very consistent and the coffee in Coq was authentic in that sense. Certainly better than the “English standard”, but then so is cow manure. (One day I might get off my old espresso high-horse, or maybe I’ll just move to Italy and shut up.)

The End

The service was great, not in-your-face as is all too common in the fancier restaurants. Pretty much a case of being there only when you want it but also always when you want it. In a rare act I actually rounded up the bill a bit on top of the auto-service-charge of 12.5%.

In the end the bill was £132.75, including the 12.5% “discretionary service charge”. That includes all the dishes mentioned above with £11.50 for a glass of wine, £3.75 for 750ml of water, and £5.00 for two espressos. Now that I scan over the bill I have to end the evening on a bit of a bum note, they charged me for a very random thing I never had! £6.75 for a “Chivas Regal”, at that price it can’t have been a very good one anyway so I’m glad I didn’t have it. How the bloody hell that ended up on there I don’t know, oh well maybe I’ll learn the lesson to check bills more carefully in future. Bit of a bummer, but £6.75 isn’t worth too much upset and I have to accept part fault for not checking the bill as I should. (And I extra-tipped these incompetents! That’s totally unfair, from experience I know how easily these mistakes can creep in and don’t go in for the conspiracy theories.)

Overall, in our experience of “known” London restaurants, we’re rating this as our second-best meal to-date. (FYI, third is “The Providores”, which I never wrote about, and first is the “Neal Street Restaurant,” now sadly no more.) We’re likely to try Coq again in the summer, since there’s a huge and well presented outdoor space on top of the building (the space inside the circle and the wings on both sized of the orange roof in this zoomed-in version of the map link above.) It looks like a beautiful spot for a classy summer lunch or dinner.

Oh, we booked through the “D&D London” website again, worked out fine.

Vim Header Guard Trick

Note: This entry has been restored from old archives.

Quite some time ago a friend of mine at work supplied us with a magical vim binding that generated safe header guards. (And copyright/licence/doxygen preamble too!) The idea is that it automatically inserts the matching (#ifndef, #define, #endif) triplet and uses a guard that incorporates the file name and a suitably long random number. (The random number is what makes it “safe”, for example what if you have a “UTIL_H” but another library you’re using also has a “UTIL_H“?)

Today I went to use the trusty old insert-guard key-binding and I see: “shell returned 127“. The problem was a simple one, the vim binding called on a script written by yet another colleague. I had copied my usual .vimrc over but not the required script so the guard failed. Since I’m easily distracted I decided to work out a way to generate the guards that wouldn’t do this to me again, rather than just scp the script onto the system! I ended up with this:

" function to insert a C/C++ header file guard
function! s:InsertGuard()
  let randlen = 7
  let randnum = system("xxd -c " . randlen * 2 . " -l " . randlen . " -p /dev/urandom")
  let randnum = strpart(randnum, 0, randlen * 2)
  let fname = expand("%")
  let lastslash = strridx(fname, "/")
  if lastslash >= 0
    let fname = strpart(fname, lastslash+1)
  endif
  let fname = substitute(fname, "[^a-zA-Z0-9]", "_", "g")
  let randid = toupper(fname . "_" . randnum)
  exec 'norm O#ifndef ' . randid
  exec 'norm o#define ' . randid
  let origin = getpos('.')
  exec '$norm o#endif /* ' . randid . ' */'
  norm o
  -norm O
  call setpos('.', origin)
  norm w
endfunction

" keymap Ctrl-g to the InsertGuard function
map <silent> <C-g> :call <SID>InsertGuard()<CR>

It is still dependent on an external command, but if vim is installed then xxd is pretty likely to be around! (Since xxd is part of the vim toolset.) I wonder if it could be shorter? I didn’t find an obvious equivalent to “basename” in vim, I suspect there might be an alternative variable to ‘%‘ that gives what I want.

An example of what it generates when you’re editing “src/util.h” and hit Ctrl-h:

#ifndef UTIL_H_668A545328A5CC
#define UTIL_H_668A545328A5CC

<existing file content>

#endif /* UTIL_H_668A545328A5CC */

Ylläs Ski Holiday 2007

Note: This entry has been restored from old archives.

This is the entry about our trip to Ylläs, pronounced oo-las (as in hoot), in Finland, where we went to learn to ski. Phew, this one took a while! I haven’t counted the hours but it adds up to many. Mainly down to fiddling with GPS data and photos! More hours if I count the individual day logs I’ve scrapped, and the first attempt at a write-up that got far too long and detailed. This one is a merging of the two and a lot shorter (would you believe!). I’ve also scrapped my plans to individually write-up the places where we dined in Äkäslompolo in favour of, very brief, coverage in this entry.

Ylläs Fell

Why Ylläs?

I prefer to try “something different” when possible, I also prefer to be where crowds aren’t. From what I read about Ylläs it would be both different and quiet, and reportedly rather good for skiing newbies! I discovered Ylläs thanks to a lastminute.com x search for cheap ski holidays, x which showed up this deal with Inghams at 50% off. (On lastminute.com x search for “Finland” as searches for “Ylläs” or “Yllas” get no results, but Ylläs is the first “Finland” result. Go figure.) After looking around on the ‘net I found a mostly positive reports on Ylläs/Inghams experiences, a reassuring start. Here’s some links from my bookmarks:

I Dislike Christmas

My overall impression from the reviews was that it was a small and very family-friendly sort of place. The family part and the very strong dose of “Christmas” involved were a little worrying, I dislike both both Christmas and children. But given the great price I decided to bite the bullet and go for it.

“Ylläs” is, in fact, the name of the overall area and also the fell (“a ridge or chain of mountains”) where the skiing is. The towns around the skiing business are Äkäslompolo and Ylläsjarvi (both also seem to be the names of the lakes next to the towns.) One for each side of the fell, one for each ski resort. We went to Äkäs (“lompolo” usually dropped), and the older ski-resort: Ylläs-Ski. On the other side of the fell the Iso-Ylläs resort can be found.

The £$€¥s

For two of us the basic price ended up being about £900, with (roughly, from memory) 550 for the actual holiday and 350 for the week-long ski school. This included return flights (Gatwick/Kittilä), bus connection, seven nights in the Äkäshotelli “hotel rooms”, plus buffet dinner and breakfast every day. The ski school, for two people, included 5 days of lessons as part of a class (less than 10 people in our class with at least two instructors), ski and boot hire, a lift pass for the entire week (covering both resorts) and free ski-bus use (between town and the ski centre, and between the ski centres on either side of the fell).

To get by day-to-day about 20€ would do two people, covering lunch and coffee. That’s utter basics though! We had a couple of proper restaurant dinners 50€ per head, and two pizzas with beers cost just over 30€ (for both of us). Note that beer is pretty expensive at the hotels and ski centres, at around 5€ for 500ml of the local brew, and as much as 7.50€ for a 600ml bottle of good Czech beer. The local beer, Lappin Kulta, isn’t bad but it very light flavoured.

If you go down to the supermarket in Äkäs you can buy the same beers for around a third of the hotel price. Might be worth stocking up if you need your beer!

In the end we spent about 350€ extra on lunches, drinks, and restaurants. We spent a bunch more on souvenir and gift items too though, they can be pretty expensive.

In this I’m ignoring the prices of all the things on offer that we didn’t do, of which there are legion! Reindeer and husky safaris, ice fishing, cross-country skiing, snow-mobiling, northern lights safaris, “visit Santa’s grotto”, etc. We went on this trip to learn to ski and were entirely focused on that.

Preparation

Ice cream on ice!
Eskimo Kat!

The preparation was mostly a matter of buying clothes. Neither of us had anything suitable for snow! We visited Ellis Brigham in London… and when it worked out that just the basics for both of us would hit near £1000 I decided to see if there were cheaper options. In the end we got most of our stuff at the budget clothes store TK Maxx (one in Watford, it’s like K-Mart/Target back in Oz I think) and the sports “warehouse” (seriously huge) Decathalon in London.

The full list of stuff includes: top and bottom thermal base layers, two fleeces each, plenty of socks, ski gloves, beanies, scarves, ski jackets, ski trousers, and ski masks. We also grabbed a more suitable (small) backpack, a new torch (LED), and some new hiking boots (good ones from Ellis-Brigham). All in all we spent about £600 on everything — a bit better than £1000 on just the thermals/fleeces/outers. Even then, after spending that much on ski gear we bloody well better go skiing again, regularly!

In our preparations two resources were most useful:

The “fruitbandit” page provides a lot of information and links on to further useful resources.

Inghams

Our holiday package was with a company called Inghams. We didn’t interact with them much since we weren’t involved in the activities, and I booked online via a different company (often good discounts available on Inghams packages through third-party resellers.) The flights (chartered) and connections all ran smoothly, and there were always representatives around to help people out (and take more money booking extras of course). No complaints about them, our holiday worked out as-advertised and without issues. That’s all I have to say about that.

The Hotel: Äkäshotelli

View From Our Room

This is, they say, the oldest hotel in the area. But not very old at only 30-something years! They have a large central building (right) where the bar, nightclub, and restaurant are located. Next to this are the “hotel rooms”, then about a 2 minute walk away are the “suites” (self contained flats really). Also, scattered around the area, were the “log cabins”.

Our hotel room was simple and fine, considering that all we wanted to do with it was sleep! In hindsight it may have been nice to have gone for a “log cabin”, and I’d recommend that as a preferred option. But note that you’ll have to trek through the snow to get to the main hotel building and the buses. The main complaint about the “hotel rooms” was the noise, after a day of skiing we just wanted to sleep at 23:00 — but there were kids screaming around the corridors until midnight, not to mention loud Poms. I, uncharitably, took to calling the building the “peasant barn”.

Our package included buffet breakfast and dinner provided by the hotel. There was a clear effort, I think, to make the Poms feel at home. While we were there they also had a bus load of Japanese tourists and provided for them boiled rice and even nori! Personally I’d prefer more “local” foods. That said, the quality of the buffet food was actually pretty good, especially the bread.

Eating in Äkäslompolo

Äkäshotelli Buffet

Äkäshotelli

I covered this briefly in the Äkäshotelli section above. I’ll add a few extra brief notes here. For the budget-concious you’d do pretty well just sticking to the buffet. Most memorable dishes include: “game” pie (like a shepherd’s pie in construction), smoked reindeer soup, baked Arctic trout, and a vast variety of pickled herring! And remember, if any culinary adventurousness is not your kettle of fish, that these are just single dishes in a fairly extensive buffet. This buffet always included some dull food for the occasional dull Pom. (Note: I’m applying stereotypes with extreme prejudice, don’t be offended Poms.) There was a definite effort to keep the runtlings happy too, with a dedicated buffet containing things like French fries and sausages (which I saw older Poms digging in to regularly).

I must mention the bread, it was good bread! Damn fresh, warm, and crusty. One loaf type was a good old wholemeal, the other seemed to be the same but contained some berries. Luckily I’m happy to throw “no refined carbohydrates” out the window on holidays, so I enjoyed plenty of this bread for both breakfast and dinner. For the dullards they also provided sliced white bread.

Desserts were on offer, they were fairly unexciting and I don’t remember the details.

Our final night was a Lappish food extravaganza! The hotel pulled out all the local staples and filled the boat (literally!) We enjoyed bloating quantities of pickled herring (three flavours!), lightly salted salmon, and game patê. The selection wasn’t as good as we’d had on a-la-carte menus, so you’ll get a better gourmet experience by going down that road, but if you leave it just to the Lappish food finalé of the Inghams package holiday you’ll do pretty well. However, I don’t know if this is a usual Inghams thing or just for the Christmas season. After this dinner a Santa showed up and the runtlings started to sing, so we left in a hurry.

Cost-wise this is going to be as good as it gets for someone on an Inghams package at this hotel, so long as you’re on half-board. To people who don’t have it included the buffet is 20€ per adult and 10€ for runtlings, which is probably OK I guess.

Äkäshotelli Restaurant (map)

Rating: Enjoyable and Interesting. We went for traditional Lappish foods, their Lappish taster plate (Lappilankku) is not to be missed. The plate included: whitefish roe, marinated wile mushrooms, small Lappish vendaces (like fresh-salted whitebait), corriander flavoured slightly salted salmon (divine!), smoked reindeer liver, potato chips (Lappish? No idea.), and compote of cranberry and onion.

The reindeer steak fillet fried in thyme butter was pretty good, but I think the steak Kat had at Poro was better. Kat especially liked the lightly salted “Ice Ocean salmon” which was almost sashimi, this was the centrepiece of her entrée. Kat’s main course was roasted Arctic Char with pesto-hollandaise and oven baked beetroot, a solid and rich seafood dish. We’re glad to note that Arctic Char has a “least concern” conservation status.

Since we were on half-board at the hotel we got 10€ per head towards the bill for dining a-la-carte instead of buffet. In the end, including a couple of glasses of wine, we paid about 90€ for this meal. (Unfortunately I’ve lost the receipt so I don’t have the details!)

Poro Restaurant (map)

Entrée @ Poro

The word “poro” means reindeer, and true to name there was plenty of reindeer on the menu. My entrée of smoked reindeer and morel soup was rich, creamy, and very enjoyable. I followed this with fried reindeer liver served with baked vegetables, the reindeer was much like calf’s liver and only a little stronger in flavour — overall this dish was good but not exciting.

Kat’s main course was a rare reindeer fillet steak served on roast Lappish root vegetables. The based was actually much the same as for my liver main. The reindeer steak was absolutely superb, the star of the show! Bloody, juicy, and tender. Kat started her meal with some salt-salmon and salmon roe on little discs of bread. Kat likes pretty much anything fishy and was happily satisfied by this dish.

We pushed our usual limits and had dessert even! Mine was an apple pie, which was fine and the only thing of particular note about it was the “spruce tip syrup”. This syrup had an unusual, and surprisingly pleasant, flavour. Kat’s dessert was cheese! Lappish “bread cheese” to be precise, warmed up and served with ice-cream and stewed cloudberries. Unusual! Certainly worth trying, the cheese is very mild in flavour so works well as part of a sweet dessert.

The décor of Poro Restaurant is of particular of note, reindeer horn, feltwork, and sharp wooden stakes (expecting a vampire attack?) all over the place. Additionally, the restaurant is attached to “Santa’s Gift Shop” where a “Santa” can be found some afternoons. (It is outside here where photographic evidence of me giving his wooden likeness a good dose of GBH was obtained.) If timed appropriately it could be a good visit with something for both the runtlings as well as breeders.

Our meal (for two) at Poro cost us 86€ and we left about a 15% tip. (My position with tips these days it “it’s too bloody hard”. So, restaurants with no service fee get a ~15% tip (if deserved) and ones with one get no extra tip. If I pay by card then if a no-service-fee restaurant gives me a card-reader with the “enter tip” screen showing they get no tip (bloody bad manners in my mind), otherwise I try to leave a cash tip. Sadly, “service fee” restaurants get their tip 100% of the time and otherwise I only tip if the service is pretty good. Then again, is getting the set “discretionary service fee” “tip” really getting any tip at all? The whole system is broken! </rant>) The 86€ includes a couple of 500ml glasses of Lapin Kulta III (pretty dull but not bad) beer at 5€ each.

Pizzeria Eväskori (map)

Eväskori Pizza!

Pizza! In Finland! Finnish pizza?! This place is to be found at the junction of the road that runs up to and around the Ylläs Fell, past Äkäshotelli, and the main road (route 940). On the inside this pizza joint is quite a sight, every wall is covered in memorabilia from ancient ski equipment to pizza plates of the world (even the ceiling a bit.)

Eväskori’s menu is rather extensive, with everything from “usuals” (think Hawaiian) to bear! Continuing on our Lappish Food Extravaganza we chose their “Ylläs Special” and “Päkäpizza” pizzas. What’s on earth are they you may ask. Well, the former apparently included karhu, savuporo, sipuli, and smentana! (That’s: bear, smoked reindeer, onion, crème fraîche.) The latter includes: savulammas, sipuli, Lapin leipäjuusto ja tomaati. (That’s: smoked lamb, onion, “bread cheese” and tomato.)

I’m glad to say that I know, now, that the Brown Bears in Finland have a conservation status of “least concern”, something I worried about at the time and ever since. Then again, if it was a concern you probably wouldn’t find it on a pizza. And honestly, minced bear on a pizza? Could have been anything. What’s our overall assessment of the pizza though? Surprisingly good! Far above trashy PizzaHut/Domino’s/PerfectPizza standards, this was a pretty decent, if very large, thin-crust pizza.

The pizzas tasted good, were not overloaded with topping, and had a good crunch around the edges. In fact they were better than half the local Italian restaurants manage. As befits the topping the flavour was pretty meaty and certainly smoky. The simplicity of them certainly precludes “gourmet”, but gourmet pizza is for try-hard pansies. A decent pizza place in Finland, believe it or not!

Our two pizzas cost us 32.40€, including 11.40€ for two Lapin Kulta III beers and an espresso. (A good espresso too, better than the English Italian-restaurant average.) The bear and reindeer pizza was 11€ and the lamb one was 10€.

Ylläspirtti (map)

Ylläs-Ski Ski Centre
Ylläspirtti @ Ylläs-Ski

The options were very limited at the Ylläs-Ski slopes, however there was a lot of new construction going on so that may change sometime soon. The ski-center (Ylläspirtti) on the Ylläs-Ski side of the fell has basics: burgers, chips, hot dogs, panini, doughnuts, etc. Plus coffee machines, filter coffee, hot chocolate (machines) and the like. No espresso, if you were wondering.

I lived on filter coffee from the urn, since the magic espresso-type machine spat out coffee that tasted like it was made from dried reindeer poop. Price examples: A filter coffee was 1.80€, a hot chocolate was 2.20€, and a croissant was 2.50€.

The Ski School & Skiing

Yvan licks snow

Skiing! It’s the whole reason we went on this trip. I’d read that it was a very good place for beginners and families, and we were certainly beginners! I’ve “seen the snow” a few of times before this trip, that was always in cities and in small volumes. Once in the distant past (1988), my family drove through The Snowies, and that was when I saw snow for the first time ever. After that I didn’t see snow again for 15 years! Skiing? I’d never even been near a ski resort! So, we travelled to Finland in the hope of learning this absurd art of “controlled falling.”

The Ylläs fell has two ski resorts. The oldest, Ylläs-Ski, is on the north side and the newer Iso-Ylläs directly opposite it on the south. We didn’t really know any details like this before going as we simply grabbed a package deal and hoped it’d work out. Our skiing experience was all on the Ylläs-Ski side, closest to the Äkäslompolo village.

As for the conditions and time of year, I’m no expert. There was snow, but it seemed rather icy and chunky at times. Some slopes were a bit like ice-gravel in places. Also, only about a quarter of the slopes were open — but this wasn’t a problem at all for us newbies (the single red and black runs in front of the ski-centre were open most of the week). This needs to be taken in climatic context though, were were in Ylläs in early December, when the season was just starting! If I take a peek at the Yllas.fi site now, three weeks later, twice as many of the lifts on the fell are operating. By later this month I assume it’ll all be in full swing. The wisdom from the locals is that March is the best time to go skiing there, the snow isn’t as good as Jan/Feb they say but the length of the days is much better (there’s actual sunlight).

The school started first thing in the morning on Monday, we got to the ski centre at 09:30 and had boots and skis fitted. Our group of about 10 newbies had four instructors on this first day. This was not an encouraging day for me! After learning not to fall over right after standing up and to “snow plough” (brake) on the baby-baby slope we went to the proper nursery slope.

Ski School
Day 1
Day 5
(Map Link)

If you look at the map above (see this map if you don’t support iframes and thus can’t see a map above) you can see my first day, as tracked by GPS, in red. The joke worth noting is the point where the red line pops away to the left, far from all the other lines, and lands on a road… that’s what I did! Shot straight off the side of the slope, hit a mound of snow, “got air” (with all the grace of camel on ice), and landed front-first on the road (ice). Next note that on the right the red line jumps out in several smaller spikes. I was still shooting off the slope for the rest of the lesson, but had learnt that the soft snow on the right was better to land on than the hard road on the left! This lesson was further reinforced by the fact that there were cars, buses, and snow-ploughs regularly speeding up and down the road and the instructor told me I’d get run over if I did that again. (Ah, teaching through fear, my favourite pedagogical methodology.) The other important lesson is to hit the ground as soon as you’re out of control, better then hitting it when you’re going twice as fast into bugger-knows-what.

On this first day I think I fell over at least twice as often as the next worst student! At the end of the day the lead instructor, Olä, asked if I was there for the 3 day or 5 day course. Me: “5 days, I think I need it”, Olä: “Yes… you do.” I wasn’t sure in the end if he thought it was a good thing I’d be there for the 5 days or if he’d prefer me to be off his slopes sooner rather than later!

What made all the difference in the end is that after the lesson that day we stayed on the slopes until they closed at 17:00. I was almost average the next day! Then every day we did the same, took our lesson in the morning then spent the rest of the day at it. I was happilly skiing backwards by the end of the week! (Not at high velocity though.)

Ski School — Slope 12
(Map Link)
Montage: Yvan Skis

Our last lesson for the week was on Saturday, after a Friday “rest day” (we spent it skiing anyway.) By this stage we’d lost four people (to frustration I think), reducing the class to about 7. Then during the last lesson one guy quit in the middle of the slope! Picked up his skis and walked to the bottom. Must have been a tough moment for him. This lesson we finished by heading to the top of the longest open “blue run”, slope 12, about 1.2km from end to end. You can see this slope on the map above as the long, really wiggly blue line. (Note: There isn’t really a road running through the middle of the slope.) Initially we just went half way up, shown where the blue line bisects the gap between the lift and the slope. Then, after the final defection, the 6 of us who remained did the full run a couple of times. To have come to this point from barely being able to stand up 6 days previously seemed astounding. So there you go, even in just one week enough dedication can get even the most astoundingly unco people (me) going on skis.

Summit Aerial

After the lesson I dragged Kat from the top of slope 12 all the way across the top of the fell to the top of the Iso-Ylläs slopes and thus the very top of the fell. Well not dragged literally, though Kat would probably have been happier if I had. As far as I was concerned the trip could not be completed without getting to the summit! (A mere 718 metres above sea-level.) Let me tell you, hiking uphill (not steep) in skis is a damn good workout. At the steepest point we did shed the skis though, there’s a point where skis become slower than just walking. You need pretty good leg muscles to get any uphill speed at all, luckily Kat and I both have pretty good strength:weight ratios.

The view was beautiful, there’s some photos here but they don’t do it justice. The most stunning thing is how flat everything is, you’re sitting on top of this isolated little “fell” in middle of a flat plain of snow covered spaces and coniferous forest . In the distance you can see some other fells, including a couple with the runway-like lighting of ski slopes (one is Pallas). There is also a more wimpy way to get to the summit, catch the bus around to Iso-Ylläs and go up on the ski-lift. When we got up there we had a look around and had a beer at the refreshment shack nearby. Then we slid our way back down to our side of the fell and spent the rest of the day on the slopes.

Lift machinery

In summary: the week was an excellent learning experience. The instructors did their job well and were very patient putting up with a bunch of unco first-timers. The slopes were pretty forgiving and there was a great range from “barely sloped” to “pretty scary”. That said, what was “pretty scary” for me it probably “pretty lame” for an experienced skier. There was only one “black run” slope at Ylläs-Ski and I’m not rating that as I never looked down it from the top even.

It’s also worth noting, I guess, that they did a great job with the runtlings. The little buggers mostly got on their skiis and were zooming around like bats-outta-hell by the end of the first day. Ah, the joy of having a low centre of gravity and no fear. (Kinda like Kat actually.) Ylläs-Ski also has a crèche, so the breeders could dump their runtlings for later retrieval.

Finalé

So, that’s it. I don’t think I have much more to add actually. We had a great time in Finland and the trip was 200% worthwhile. I can’t say I particularly loved the saturation of families with children, but, as much as runtlings annoy me, fashion-obsessed social wannabes piss me off much more. Major bonuses were interesting food, guaranteed snow, great ski instructors, and no crowds.

Phew, this has been the most time consuming and long-winded entry ever… Well done if you made it this far, I nearly didn’t. If you’re thinking of going to Ylläs or another Lapland destination I hope I was of some help.

Here’s a link to our full Ylläs Ski Holiday photo album.

Panorama: From the top of Ylläs fell

Appendix A: Maps

Thanks to my carrying around of some geek bling, namely a GPS unit, I was able to map several of our walks, bus routes, and skiing days. I’ve compiled some of the cleaner routes and the way-points into a KML file, this can be viewed in both Google Earth and Google Maps. The main use has been for the embedded maps in this entry. If you like you can view the map in it’s entirety or just download the KML file.

The KML file could be converted into various formats to be uploaded to GPS devices too. I highly recommend the gpsbabel tool if you’re thinking of doing something like that. I wrote about the process of Crafting KML from Garmin GPS Data previously.

The coolest map section from our trip was that of the ski slopes. I individually mapped the ski lifts we used and also mapped each slope, carefully skiing from edge to edge to get wiggly lines. The slopes, minus the messy lesson tracks, are shown in the map below. The wiggly lines are downhill slopes, and the straighter ones cross-country. Green is “very easy” and blue is “easy”, we didn’t do any “medium” or “hard” tracks. The straight dark grey lines are ski lifts. The cross-country line at lowest on the map is from the top of the Ylläs-Ski slopes across to the Ylläs summit (marked with the arrow.)

Some Ylläs-Ski Slopes and trail to summit
(Map Link)

Alas, Google Maps “iframes” make my XHTML-strict validation fail 🙁

Appendix B: Photos

Yvan and Kat

Many of photos taken, thus many of photos culled, but still so many left! Google’s Picasa tool is what I use for adjusting photos these days. I wanted to do some stitched panoramas too. Luckily for me I found a critter that did a far better job than I could!

The critter is hugin, while slow (forgivable thanks to to great job it does) and with a clunky UI (we’ll let that pass), it did an amazing job of joining up photos. For two sets of three I didn’t have to interfere at all, entirely automatic! For the third set of three I pointed out some correlated features and it did the rest beautifully. The last panaroma shown in the entry is one of the stitched ones. It’s important to know the “crop factor” of your camera, I found a page explaining sensor sizes that was very useful (skim down to “Addendum: The crop factor:”.)

Grokking Oopses

Note: This entry has been restored from old archives.

Introduction

Man it was hard to find information on debugging 2.6 kernel issues, maybe my Google skills need honing. Recently I was parachuted into a customer site on a support-or-die mission. The problem: kernel-space. My problem: not much kernel-space experience. A week of little sleep, much reading, and some learning. In the end the problem was rooted out and the crack team of kernel monkeys back at base blew it out of the water. Hooray!

This is the first in a trilogy of entries I intend to write. This one discusses a specific example of an “Oops” in detail, giving a line-by-line description of everything the oops tells you. Well, almost everything, some details go too deep to cover in something this introductory… to drill all the way down could take a whole textbook.

The second entry goes into relating the oops to the original code, I might call it “tracing assembly”. The third entry will delve into a session of debugging with ‘kdb’.

Now the first two entries will certainly happen as almost all the material was written during my work trip. (Joyful hours of trains, flights, and just plain waiting at stations and airports.) I won’t make any promises about the ‘kdb’ entry though, since I’ve written nothing for it and would need to spend quite a bit of time generating examples and traces.

Important items of note:

  • An IA32/i386 architecture/kernel is assumed, the oops code is platform dependant.
  • The oops examined here comes from a 2.6.16 kernel.
  • Sometimes file paths are given, these are relative to the root of a Linux 2.6.16 source tree.
  • This entry deals with a specific oops for a specific error case and doesn’t discuss much beyond the specific example.
  • There’s no guarantee, as far as I know, that the oops format won’t change at some time.

Finally, a disclaimer: I am not a kernel developer. In fact I learnt a couple of new things just writing these two entries. No doubt there are important facts I’ve missed or not rated highly enough. Maybe it is even possible that I’ve got something plain wrong (if so please correct me via the comments or email).

Oops!

Let us start where these things usually start, a kernel oops:

kernel: Unable to handle kernel paging request at virtual address 68230a7d
kernel: printing eip:
kernel: c0143742
kernel: *pde = 00000000
kernel: Oops: 0000 [#1]
kernel: SMP 
kernel: Modules linked in: monkey_pkt_eater nfnetlink_queue xt_condition
    iptable_ips edd ide_cd ip_nat_ftp ip_conntrack_ftp ipt_REDIRECT xt_tcpudp
    ipt_addrtype ebtable_nat ebtables ip_nat_mms ip_nat_pptp ip_nat_irc
    iptable_nat ip_conntrack_mms ip_conntrack_pptp ip_conntrack_irc af_packet
    ipt_logmark ipt_CONFIRMED ipt_confirmed ipt_owner ipt_REJECT sr_mod cdrom
    usb_storage evdev microcode parport_pc ppdev parport xt_state xt_NOTRACK
    iptable_raw iptable_filter ip_conntrack_netlink ip_nat ipt_LOG ip_conntrack
    ip_tables x_tables nfnetlink_log nfnetlink monkey e1000 capability
    commoncap loop sg ahci libata sd_mod scsi_mod
kernel: CPU:    0
kernel: EIP:    0060:[<c0143742>]    Tainted: PF     VLI
kernel: EFLAGS: 00210202   (2.6.16.43-54.5-smp #1) 
kernel: EIP is at put_page+0x2/0x40
kernel: eax: 68230a7d   ebx: 00000001   ecx: f1057680   edx: 68230a7d
kernel: esi: f6fe7600   edi: fe089b98   ebp: f64d3c14   esp: f64d3bbc
kernel: ds: 007b   es: 007b   ss: 0068
kernel: Process snort_inline (pid: 6298, threadinfo=f64d2000 task=dff3fa70)
kernel: Stack: <0>c02a8b4a f6fe7600 f1057020 c02a88d8 000004cd f9de0fdd c7af5000 f7802b60 
kernel: 0000c7af fe73e860 f64d3c48 f64d3c48 e7e19834 f64d3c34 f5b54cc0 00000000 
kernel: 00000001 c02c7adf 00200282 d94bd4cc f64d3c48 f4429a40 f64d3c40 f9dd912a 
kernel: Call Trace:
kernel: [<c02a8b4a>] skb_release_data+0x8a/0xa0
kernel: [<c02a88d8>] kfree_skbmem+0x8/0x80
kernel: [<f9de0fdd>] mkyDestroyPacket+0x9d/0x260 [monkey_pkt_eater]
kernel: [<c02c7adf>] ip_local_deliver_finish+0xef/0x270
kernel: [<f9dd912a>] mkyIpqPostHandler+0xda/0x140 [monkey_pkt_eater]
kernel: [<c02c79f0>] ip_local_deliver_finish+0x0/0x270
kernel: [<f8e9e182>] find_dequeue_entry+0x82/0x90 [nfnetlink_queue]
kernel: [<f8e9e1ab>] issue_verdict+0x1b/0x50 [nfnetlink_queue]
kernel: [<f8e9f5af>] nfqnl_recv_verdict+0x1ff/0x330 [nfnetlink_queue]
kernel: [<c0308730>] schedule+0x350/0xdd0
kernel: [<f887940e>] nfnetlink_rcv_msg+0x16e/0x200 [nfnetlink]
kernel: [<f8879542>] nfnetlink_rcv+0xa2/0x169 [nfnetlink]
kernel: [<c02beecd>] netlink_unicast+0x16d/0x250
kernel: [<c02bf462>] netlink_data_ready+0x12/0x50
kernel: [<c02be2d1>] netlink_sendskb+0x21/0x40
kernel: [<c02bfacd>] netlink_sendmsg+0x27d/0x320
kernel: [<c0116c88>] __wake_up+0x38/0x50
kernel: [<c02a2b2e>] sock_sendmsg+0xae/0xe0
kernel: [<c012f4c0>] autoremove_wake_function+0x0/0x50
kernel: [<c012f4c0>] autoremove_wake_function+0x0/0x50
kernel: [<f90caa7f>] monkey_chan_queue_append+0x15f/0x170 [monkey]
kernel: [<c02a9e4a>] verify_iovec+0x2a/0x90
kernel: [<c02a306d>] sys_sendmsg+0x15d/0x270
kernel: [<c02a3f86>] sys_recvfrom+0x116/0x140
kernel: [<f90557c0>] e1000_clean_rx_irq+0x0/0x3d0 [e1000]
kernel: [<f9053b0e>] e1000_clean+0x53e/0x780 [e1000]
kernel: [<f90c7780>] mkyGetState+0x20/0x30 [monkey]
kernel: [<f9ddbc90>] packet_writer+0x2e0/0xd50 [monkey_pkt_eater]
kernel: [<c02a453f>] sys_socketcall+0x24f/0x280
kernel: [<c013a5b0>] __do_IRQ+0xc0/0x110
kernel: [<c0102d3f>] sysenter_past_esp+0x54/0x75
kernel: Code: c0 8b 01 01 c2 83 fa 10 89 11 7f 05 83 fa f0 7d 0d f0 01 15 fc 8f
    40 c0 c7 01 00 00 00 00 c3 8d 76 00 8d bc 27 00 00 00 00 89 c2 <8b> 00 f6
    c4 40 75 1e 8b 42 04 40 74 1f f0 83 42 04 ff 0f 98 c0 

(This oops has had some timestamp details removed and has been wrapped for neatness. Also, some “proprietary symbols” have been renamed, let us just say: beware the monkey.)

Tackling the oops

Let me first say: Thanks to the Internet containing cruft from all ages you’ll find many references to ksymoops when researching kernel oopses. Stop now! Maybe add a “-ksymoops” to your search query, though this may remove several good links. It really is a battle against accumulated information. The ksymoops tool was useful for dealing with Linux 2.4 oopses, but in 2.6 it’s work is done at oops-time and ksymoops is useless. If you’re dealing with 2.6 forget about ksymoops.

On with the oops. It tells us quite a lot about what was going on when the it occurred, we have the stack, the call path, the content of registers, and more. On inspection much of this is pretty straight forward to someone familiar with Linux, C programming, and Intel CPUs and assembly (be aware of GAS). It’s probably very hard going for someone who hasn’t done any work at that sort of level, but difficulty is just a good opportunity to learn! Right? However, like me, you don’t need to be a hard-core kernel hacker (I’m not even soft-core, I’d barely earn a PG rating) to get an idea of what’s going on.

Line by line

kernel: Unable to handle kernel paging request at virtual address 68230a7d

The core problem, and an oft-seen one, think of this as the “segfault” of the kernel. In actual fact both userspace nd kernelspace memory access violations come from the same place (MMU) and are handled by the same code. Generation of the oops text starting with this line has it’s origins in do_page_fault in the arch/i386/mm/fault.c code file. Think of that path as “i386 memory manager faults”. (“faults” covers a bunch of conditions, not just access violations.)

In short: something in the kernel has tried to use an address that doesn’t work, and that address was: 0x68230a7d.

kernel: printing eip:
kernel: c0143742
kernel: *pde = 00000000

Eip! It sounds like a small rodent’s cry of distress. It’s actually the “Extended Instruction Pointer”, which is the CPU register containing the address in memory of the instruction being executed. Thinking back to computer architecture classes you might be more familiar with this as the “Program Counter”. This tells us that at the time of the invalid paging request the instruction at address 0xc0143742 was being executed. A most useful bit of information that we’ll return to several times.

The “PDE” is the “Page Directory Entry”, and I’m not going to pursue that further. Try this article by Robert Collins, published in DDJ back in ’96, for more information: Understanding 4M Page Size Extensions on the Pentium Processor.

There’s a seriously large amount of information behind this that is worth reading up on. For starters try Google mixing “Linux Kernel” with a variety of things like “virtual memory”, “paging”, “mmu”, … From my bookshelf I’d recommend Chapter 2 of Understanding the Linux Kernel. That book is fairly bent towards Intel, I don’t have a book that covers deeper Intel specifics and can only recommend you make use of Google.

kernel: Oops: 0000 [#1]
kernel: SMP 

Now we’ve jumped to output generated by the die function in arch/i386/kernel/traps.c.

The first number is actually the error_code value passed to do_page_fault printed in hex. The interpretation for this is:

 *  bit 0 == 0 means no page found, 1 means protection fault
 *  bit 1 == 0 means read, 1 means write
 *  bit 2 == 0 means kernel, 1 means user-mode

So 0000 means “no page found” on “read” in “kernel” mode. This checks out with what we already know, consistency is good.

The number in the square brackets is the oops count. It is the number of times this die function has been called since boot, counting from 1. Usually you only want to worry about the first oops that you find. Everything after that point could be a side-effect of earlier kernel badness. If you’re working past the first oops then anything I have written here will be old news to you.

Yeah, and it is an SMP kernel. Other strings that may appear here are PREEMPT, and DEBUG_PAGEALLOC. After this the somewhat mis-named show_registers function found in arch/i386/kernel/traps.c is called and the rest of the oops text is generated in or below this call.

kernel: Modules linked in: monkey_pkt_eater nfnetlink_queue xt_condition
    ...

This output is generated by a call to print_modules (kernel/modules.c) by show_registers. Usually one of these will be the culprit for your problem, module code tends to be less stable than core kernel code, especially proprietary modules!

kernel: CPU:    0

This message is coming from CPU 0. Obvious enough?

kernel: EIP:    0060:[<c0143742>]    Tainted: PF     VLI

Eip! Again. The value 0060 comes from the CS register, let’s ignore it. (Sorry!) After that we have the EIP address 0xc0143742 shown again. Now “Tainted“, sounds nasty doesn’t it? There are six single-char codes here, and they’re generated by the print_tainted function in kernel/panic.c. The codes represent a bunch of undesirable, yet legal, things that might have been done to the kernel. The first code either ‘P‘ or ‘G‘, if the former then a non-GPL module has been loaded (as is the case here). If you have a ‘P‘ then don’t expect much support from kernel.org developers, unless the problem is obviously not related to non-kosher kernel modules. You’ll either want to work out the problem yourself, reproduce the problem without the proprietary module loaded, or get help from the vendor responsible for said module.

I’ll take a short-cut now and rip the comment from print_tainted to give the full list of flags:

 *  'P' - Proprietary module has been loaded.
 *  'F' - Module has been forcibly loaded.
 *  'S' - SMP with CPUs not designed for SMP.
 *  'R' - User forced a module unload.
 *  'M' - Machine had a machine check experience.
 *  'B' - System has hit bad_page.

The alternative character to all except ‘P‘ is a blank space (i.e. flag is unset). In our oops we also have an ‘F‘ because one of the custom modules loaded is missing symbol version information. The ‘F‘ flag can come into the mix for a variety of reasons it seems, the canonical one being that `insmod -f` was used to load it. None of the other “taints” are flagged in my example so I’m not going detail them. (See the bottom of Documentation/oops-tracing.txt for information.)

One last note on “taint”: Once a kernel is tainted it stays tainted. I.e. if you load a propriety module it taints the kernel and the ‘P‘ taint flag remains even if you unload it. You could think of it as an “from here on in all bets are off” state.

After the taint flags we have “VLI” and I don’t have a clue what this signifies. This is hard-coded in the i386 traps.c file, since it isn’t variable within the architecture I’ll dismiss it as unimportant!

kernel: EFLAGS: 00210202   (2.6.16.43-54.5-smp #1) 

This line first gives the CPU’s EFLAGS register, this register stores all the usual flags like “carry” as well as a bunch of less familiar flags (see link for more detail). After the flags, in brackets, is the version string identifying the kernel that generated the oops.

kernel: EIP is at put_page+0x2/0x40

Eip! Yet again, but now with some more useful information. The symbol attached to the code into which EIP is pointing along with EIP’s offset from the symbol (0x02) and the size of the code associated with the symbol (0x40, distance between the put_page symbol and the next marked symbol).

kernel: eax: 68230a7d   ebx: 00000001   ecx: f1057680   edx: 68230a7d
kernel: esi: f6fe7600   edi: fe089b98   ebp: f64d3c14   esp: f64d3bbc
kernel: ds: 007b   es: 007b   ss: 0068

Now we finally get the actual named purpose of the print_registers function: a dump of the content some CPU registers. It’s worth noting at this point that %edx and %eax both contain our dodgey address.

kernel: Process snort_inline (pid: 6298, threadinfo=f64d2000 task=dff3fa70)

Information about the current “process” being run on the CPU including pointers to the process’s thread and task structures. There will always be some process, but it may or may not be directly related to the error that caused the oops. When you’re debugging don’t jump to conclusions without good reason, keep following the trail of the oops.

kernel: Stack: <0>c02a8b4a f6fe7600 f1057020 c02a88d8 000004cd f9de0fdd c7af5000 f7802b60 
kernel: 0000c7af fe73e860 f64d3c48 f64d3c48 e7e19834 f64d3c34 f5b54cc0 00000000 
kernel: 00000001 c02c7adf 00200282 d94bd4cc f64d3c48 f4429a40 f64d3c40 f9dd912a 

The stack. Simply each word starting at %esp (stack pointer) and continuing
to the base of he stack or for kstack_depth_to_print words, a limit
configurable at kernel compile time. Some values in the stack can be related
to the next part of the oops, the “Call Trace“. Essentially, starting with the
at %esp the call chain is traced:

kernel: Call Trace:
kernel: [<c02a8b4a>] skb_release_data+0x8a/0xa0
kernel: [<c02a88d8>] kfree_skbmem+0x8/0x80
kernel: [<f9de0fdd>] mkyDestroyPacket+0x9d/0x260 [monkey_pkt_eater]
kernel: [<c02c7adf>] ip_local_deliver_finish+0xef/0x270
kernel: [<f9dd912a>] mkyIpqPostHandler+0xda/0x140 [monkey_pkt_eater]
kernel: [<c02c79f0>] ip_local_deliver_finish+0x0/0x270
kernel: [<f8e9e182>] find_dequeue_entry+0x82/0x90 [nfnetlink_queue]
kernel: [<f8e9e1ab>] issue_verdict+0x1b/0x50 [nfnetlink_queue]
kernel: [<f8e9f5af>] nfqnl_recv_verdict+0x1ff/0x330 [nfnetlink_queue]
kernel: [<c0308730>] schedule+0x350/0xdd0
kernel: [<f887940e>] nfnetlink_rcv_msg+0x16e/0x200 [nfnetlink]
kernel: [<f8879542>] nfnetlink_rcv+0xa2/0x169 [nfnetlink]
kernel: [<c02beecd>] netlink_unicast+0x16d/0x250
kernel: [<c02bf462>] netlink_data_ready+0x12/0x50
kernel: [<c02be2d1>] netlink_sendskb+0x21/0x40
kernel: [<c02bfacd>] netlink_sendmsg+0x27d/0x320
kernel: [<c0116c88>] __wake_up+0x38/0x50
kernel: [<c02a2b2e>] sock_sendmsg+0xae/0xe0
kernel: [<c012f4c0>] autoremove_wake_function+0x0/0x50
kernel: [<c012f4c0>] autoremove_wake_function+0x0/0x50
kernel: [<f90caa7f>] monkey_chan_queue_append+0x15f/0x170 [monkey]
kernel: [<c02a9e4a>] verify_iovec+0x2a/0x90
kernel: [<c02a306d>] sys_sendmsg+0x15d/0x270
kernel: [<c02a3f86>] sys_recvfrom+0x116/0x140
kernel: [<f90557c0>] e1000_clean_rx_irq+0x0/0x3d0 [e1000]
kernel: [<f9053b0e>] e1000_clean+0x53e/0x780 [e1000]
kernel: [<f90c7780>] mkyGetState+0x20/0x30 [monkey]
kernel: [<f9ddbc90>] packet_writer+0x2e0/0xd50 [monkey_pkt_eater]
kernel: [<c02a453f>] sys_socketcall+0x24f/0x280
kernel: [<c013a5b0>] __do_IRQ+0xc0/0x110
kernel: [<c0102d3f>] sysenter_past_esp+0x54/0x75

Think of this as analogous to “bt” in gdb, it is generated by show_trace_log_lvl in arch/i386/kernel/traps.c. But be aware that it can be broken, what if your bug involved mucking up data on the stack?

What we know at this point is that the put_page where our problem occured was called by skb_release_data (aha! networking code!), which in turn was called by kfree_skbmem, and that by mkyDestroyPacket. That last item, from the monkey_pkt_eater module comes from our propriety code. Our suspicion is that we have, for some reason, given some bad data to kfree_skbmem.

kernel: Code: c0 8b 01 01 c2 83 fa 10 89 11 7f 05 83 fa f0 7d 0d f0 01 15 fc 8f
    40 c0 c7 01 00 00 00 00 c3 8d 76 00 8d bc 27 00 00 00 00 89 c2 <8b> 00 f6
    c4 40 75 1e 8b 42 04 40 74 1f f0 83 42 04 ff 0f 98 c0 

Personally I find this the most exciting part of the oops. A sequence of hex values, joy! But what is the “Code:“? Quite simple really. The kernel takes the value of EIP, subtracts 43 then prints out 64 bytes from that point, marking the byte at EIP with <..>. I.e. it is a hexdump of the section of machine code being run at the time the oops occurred. And this means we can disassemble.

But it might not be so straight forward as we’d like. That “-43” means the hex-dump could start anywhere, maybe right in the middle of an instruction. So I suggest either removing everything prior to EIP (remove everything before <8b>) or starting at the symbol address that EIP maps into. The latter option is only going to work if the offset from the symbol is less than 43, in our case we’re lucky because in put_page+0x2/0x40 we’re given that the offset is only 2 bytes, so we can safely cut the code down to this:

    89 c2 <8b> 00 f6 c4 40 75 1e 8b 42 04 40 74 1f f0 83 42 04 ff 0f 98 c0 

Now we can employ trusty xxd to reverse the hex to a binary file:

:; echo '89 c2 8b 00 f6 c4 40 75 1e 8b 42 04 40 74 1f f0 83 42 04 ff 0f 98 c0' | 
    sed 's/[^0-9a-f]//g;s/^/0: /' |  
    xxd -r  -c 256 > code.bin

What do we do with this code.bin file? Our next friendly tool is objdump, which won’t accept data from STDIN or using <(...), thus the temporary code.bin file rather than a pipe. With objdump we do and get this:

:; objdump -b binary -m i386 -D code.bin 

code.bin:     file format binary

Disassembly of section .data:

0000000000000000 <.data>:
   0:   89 c2                   mov    %eax,%edx
   2:   8b 00                   mov    (%eax),%eax
   4:   f6 c4 40                test   $0x40,%ah
   7:   75 1e                   jne    0x27
   9:   8b 42 04                mov    0x4(%edx),%eax
   c:   40                      inc    %eax
   d:   74 1f                   je     0x2e
   f:   f0 83 42 04 ff          lock addl $0xffffffff,0x4(%edx)
  14:   0f 98 c0                sets   %al

Some really hard-core people familiar with machine code read it like assembly, and can easily work out the instruction sequence prior to put_page too. But if that was you then you wouldn’t be reading this I think.

What we know now is that the oops occurred in the assembly above at offset 2, at “mov (%eax),%eax“. Which is moving the word at the address stored in %eax into %eax. We can surmise that our invalid address is stored in %eax, and looking further up the oops, at the register dump, we see that the value in %eax is 0x68230a7d and that is the bad address that the very first line of the oops gives us. We now know the exact problem, but it isn’t really any use to use without some context isn’t it?

Thinking a little further, we know that offset 0 in the assembly code above is the entry point of the put_page function so the only code belonging to the function prior to where the error occurs is “mov %eax,%edx“. Logically it seems that an argument to the put_page function was provided in %edx (which the register dump shows also contains 0x68230a7d), and that this argument provides the bad address.

At this point we still don’t have any useful context and really need to start looking at a more complete picture of the code involved. That’s the subject of the next entry in this series.

[With some amusement I note that during the week I was dealing with the problem that prompted me to write this stuff the topic of “decoding oopses” became somewhat popular on LKML! Heh, great timing. This renders my own efforts somewhat redundant, oh well.]

January 2008 Goodies

Note: This entry has been restored from old archives.

Yes, Ylläs (and some other) entries are still going to happen! From 09:00 last Sunday through to 23:00 last Friday 100% of my computer/net time belonged to work. I was in Germany dealing with some stuff. Getting back late on Friday night I turned off all the computers and spent the entire weekend computerless. A rare luxury, but one that means that things don’t get done.

When I got back from Germany a box of goodies from my mum back in WA was waiting for me. Plus, I grabbed a couple of bottles of whisky from the tax-free in Heathrow. Plus, we did a trip into London on Saturday and visited a catering store and Borough Market.

January 2008 Goodies

The image above contains, left-to-right & top-to-bottom:

  • Quattro Foglie ORO — Extra virgin olive oil from the EEVO stall at Borough Market.
  • Mum’s Quince Jelly — My all time favourite!
  • Promite — Never found this in the UK, I hate Vegemite and love Promite.
  • Mum’s Brinjal Ajvar — An Indian eggplant chutney, Kat’s favourite (she eats it from the jar if I’m not looking!)
  • Mum’s Duhhah — Perfect with the EEVO we got!
  • Mum’s Indian Tomato Kasundi — Great with everything.
  • Mum’s Tangerine Dream marmalade — Never tried it but it’ll be good.
  • Three wines from “back home” — The brute force of Aussie wines is quite a shock after months of mellower wines.
  • Aberlour 12yo — My favourite of the two, sweet and smooth.
  • Cragganmore “Distillers Edition” — Good solid flavour, maybe a “lighter” cousin in flavour to my favourite: Lagavulin 16yo. (No apostrophe on the bottle?!)

We also grabbed a couple of great cheeses, including the organic, unpasteurised Stilton that I can’t get enough of. At the catering shop we just picked up a few things missing from the inventory:

  • Butter Dish — I hate keeping butter in the fridge but we didn’t really have a spare dish with a cover and couldn’t be bothered with cling-flim.
  • Food Mill — The best way to make many soups and tomato sauce, alas, not the classic Moulin (the one they had was too big and too expensive).
  • Mandolin — Again this isn’t the mandolin but an 80% cheaper Japanese rip-off. Will see how long it lasts.
  • Conical sieve set — Hard to find but most useful, they didn’t have any muslin unfortunately but that’s easy to find elsewhere.
  • Grater — It is so hard to find a good grater!
  • Oil Jars — With pouring spouts so I don’t get an oily thumb and don’t splosh too much EEVO on dinner.

Joy.