Future in the Past

The other day, while reading William Gibson no less, I paused to consider the term ‘Virtual Reality.’ I’ve encountered this term on both sides of its existence, even though it has never existed, never could. During my undergraduate work, In one of my computer science classes, I had a professor who specialized in virtual reality. I remember having to read and study papers and books on the coming period of ubiquitous virtual reality, the kind most often associated with visors, haptic gloves, visual implants, 3D sound, holodecks. We studied an always future future. I remember throwing that textbook away many years ago during a move, knowing I was not going to need it again.  At some point, I’m not sure when exactly–perhaps when VRML ceased to be talked about–the term ‘virtual reality’ appears to have stopped being future in the future and become future in the past. When I hear the term now, I am simultaneously aware of both its historic and future connotations, the idea vibrating between the past and present, the real and the virtual. In this sense, I suppose the term has succeeded wildly, in that ‘virtual reality’ was always, and only, virtual reality.

Posted in Idea Factory | 1 Comment

How to crash like you mean it

I lost most of a day today trying to track down a bug in our Pointer Lock (nee Mouse Lock) implementation.  We’re literally within inches of being done this patch, and to be honest, I need to get it done so I can focus on other projects.  However, as is the case when programming, being close simply means you use smaller units to measure your distance, not that you reduce the number of steps.  I’m hopeful that we’ll have this thing back into review by mid-week.  But first a digression while we fix a newly discovered crash bug.

Raymond, Steven, Diogo and myself have been collaborating on the final implementation details and the tests.  Today I landed the bulk of the tests in my branch, which Raymond and Steven had written and/or fixed over the past few weeks.  I was keen to see how things stood, since Diogo and I had also rewritten some key parts of our code this week.  I ran the tests and 5 or 6 tests in, my browser crashed.  I hadn’t even had coffee yet (heya, Monday!).

Steven was online and quickly offered to fix the tests.  But I told him what I’m going to tell you right now: no web page (our tests are just HTML, CSS, and JavaScript–simple web pages) should ever be able to crash the browser.  Never.  Ever.  If you can crash the browser with JavaScript, it’s a browser bug, not (only) your bug.  I talk to lots of good web developers who all seem to think they’ve done something wrong when the browser crashes.  It’s never the web developer’s fault, because nothing in that page should be capable of causing the crash.  That isn’t to say that their code doesn’t do something odd, unique, or incorrect.  Doing something wrong is not the same as crashing.  Remember that.  If you can crash the browser, you should report the bug–it might even be worth something, if it’s an exploitable security issue (not all crashes are).

Unfortunately reporting this crash just meant swiveling around in my chair, so as to face the reflection in my second monitor.  The first thing you need when you crash is to know where you’re crashing, often called a ’stack trace,’ or just a ’stack’.  There are various ways to accomplish this, depending on the circumstances under which you crash.  Your standard Firefox browser keeps track of these via about:crashes (i.e, type that into your address bar).  Here you can see a list of crashes you’ve had (I have lots, maybe you have none).  If you click any of your crashes, you’ll be taken to Mozilla’s Crash Server, which will, among other things, allow you to see your crash stack.

This isn’t possible in my case.  I’m running a local debug build that I made, which isn’t hooked up to the crash server.  However, because I’ve made this build, and because it has debug symbols already (you want to make debug builds while you’re working on bugs for this very reason), I can simply attach my debugger to the browser before I crash, trigger the bug, and then look at the crash stack.

When you’re doing Mochitests, as we are, you can run your tests in a few different ways.  If you want to have time to attach your debugger to the running browser before the tests start, and then crash, you can do this:

python ./objdir-debug/_tests/testing/mochitest/runtests.py
  --test-path=dom/tests/mochitest/pointerlock

This runs the test runner, starting a simple web server and the browser, and points it at just the tests specified in the dom/tests/mochitest/pointerlock directory.  NOTE: before you do this, make sure your tests are copied into the object directory (i.e., make -C objdir-debug/dom/tests/mochitest).

Now you can attach your debugger (get your browser’s PID using ps or the like, then run gdb and type: attach <pid>).  Once connected to your running process, and all symbols loaded, you can tell the debugger to let your browser continue (in gdb, type ‘continue’).  Run your tests, and if all goes well, you’ll crash.

When I crashed this time, my debugger instantly came to life, and I was able to ask for a stack trace (e.g., a ‘backtrace’ in gdb, using the ‘bt’ command).  The full stack is here, but the top few frames (e.g., function calls) tell the story:

#0  ... in nsIFrame::GetStyleContext (this=0x0) at nsIFrame.h:716
#1  ... in nsIFrame::PresContext (this=0x0) at nsIFrame.h:546
#2  ... in nsIFrame::GetScreenRect (this=0x0) at /Users/dave/repos/mozilla-central/layout/generic/nsFrame.cpp:4197
#3  ... in nsEventStateManager::GetMouseCoords (this=0x10033ff20) at /Users/dave/repos/mozilla-central/content/events/src/nsEventStateManager.cpp:4136
#4  ... in nsEventStateManager::SetPointerLock (this=0x10033ff20, aWidget=0x127d2f240, aElement=0x119c70f80) at /Users/dave/repos/mozilla-central/content/events/src/nsEventStateManager.cpp:4111
#5  ... in nsDOMMozPointerLock::Lock (this=0x119adc190, aTarget=0x119c71000, aSuccessCallback=0x11b81a680, aFailureCallback=0x11b81a6a0) at /Users/dave/repos/mozilla-central/dom/base/nsDOMMozPointerLock.cpp:293

Here’s what this says. At some point nsDOMMozPointerLock::Lock() was called, which is what happens when the user calls navigator.mozPointer.lock() in JavaScript. This in turn called nsEventStateManager::SetPointerLock(), which stores a reference to the locked element on the nsEventStateManager. Part of that process involves figuring out where the mouse pointer is at the time of lock, since the spec says we need to keep track of this position so that we can return the mouse there when we unlock. The call to nsEventStateManager::GetMouseCoords() is where things go off the rails, as it tries to get dimensions for the element’s frame in the page–notice nsIFrame::GetScreenRect (this=0x0). The “this=0×0″ shows us we are calling a method on a null pointer; in other words, we have no frame for this element.

It’s definitely our code that’s causing the crash (our C++ code, that is). Now we have to figure out why. For the next little while we tried to isolate the specific test that was causing the issue. That turned out to be a losing battle, since we have so many tests, and since it seemed (initially) like it might be related to the interaction of multiple tests run in a particular order. Was it an OS X only bug? We didn’t seem to hit it very often on Linux. The fact that it didn’t crash every time was also frustrating.

Reducing it down to a particular test wasn’t going to work. We needed to understand why an element would not have a frame. I asked on irc, and instantly got the same answer from two people: display:none. Why does CSS hate me so? If you style an element display:none, it won’t have a frame, since it won’t be visible. Seems so obvious. But why were we hitting this in our tests? Surely no one would use display:none in…our…tests. Yet here were two cases of it:

<iframe id="iframe" style="display: none" ... >

...

<div id="content" style="display: none">
  <canvas id="canvas" width="150" height="150"></canvas>
</div>

Many, many tests in Firefox hide content that isn’t relevant to the test, and normally it wouldn’t matter. But in this case, it made a lot of difference. So first, we need to remove those display:none styles. But we also need to protect against an element not having a frame when lock is called, and losing its frame once locked (display:none style added after being locked). By doing these simple checks, we won’t crash in the future, no matter what the web developer does with the display style.

I wanted to write about this for my students who are doing work like this all semester, and will inevitably hit an issue like this in their own code. Crashes can be really useful when you have a strategy for using them to your advantage.

Posted in CDOT, Implementing Mouse Lock, Mozilla Education, Seneca, Teaching Open Source | 2 Comments

One needs models: on being dad

I saw this first when Corban tweeted it (every cool music thing I hear comes from him first), but since then it’s come at me from all kinds of people.  I love this, and I also love being a dad.

Posted in Home School, family | 1 Comment

A Harvest Table

For many years, my wife and I have wanted to get a harvest table.  Between cooking, eating, and home school we spend a lot of time as a family around a table.  Philosophically as well as practically, the central organizing role of a well-made table is important to the functioning of our family.

There are literally hundreds if not thousands of options available.  We’ve spent lots of time going to look at them, and been on the verge of buying one a few times.  However, every time we found one, it came with compromises: the length or width was wrong, the legs meant chairs couldn’t be be pushed in, the skirt was so low you couldn’t cross your legs.  It became clear that we’d need to have something made.

We live near one of the larger populations of Mennonites in Ontario, and some of the best harvest tables we’ve seen come from their workshops.  But which one?  My wife, as is often (always?) the case, managed to solve this and found a small shop near here that seemed to have promise.

HD Threshing builds harvest tables by hand in the style we wanted out of reclaimed Ontario barn boards and beams.  Their tables are made of Pine or Hemlock (we chose the latter), because that’s what the barns were made of a hundred+ years ago.  Living in rural Ontario, I loved the fact that the table was not only made here, but made of wood that had been part of the landscape as well.  Their process involves sanding, but no planing of the wood, leaving all the centuries old weathering and character of the wood in tact.  Rather than staining or painting with a color, they choose instead to use an epoxy finish, in order to give an indestructible finish, while still allowing the wood to show through.  It creates a surface you feel compelled to touch–even though you know it’s smooth, you can’t believe it to look at the distressing and character of the wood.

HD Threshing is a small shop run by a group of passionate, young guys.  The owner toured us through the shop, showing us all the different things we could have, and helping us understand what the end product would look like.  We were able to choose every aspect of what we got.  I loved everything about the process and the end product.

Here’s some pictures of our new harvest table:

Posted in Home School, Idea Factory, family | 2 Comments

Beyond Reality TV: The New Acting

The new acting requires new skills.  Where once an actor took a role in a film, television show, &c., the new acting disperses the subject across media, and increasingly, traditional, everyday media.  Where once the actor produced a body of work, the new acting is the body of the actor.  Distribution, we used to understand, meant the meting out of copies, whether to individuals or networks.  Today the work finds distribution a page at a time–magazine covers, tweets, 911 calls–and those pages scattered across every form of media, a play written ahead of time and seemingly carried out the window of the playwright by the wind, slowly, sorrowfully, inevitably falling to the ground, falling where it may.  The new acting creates through destruction, specifically the destruction of the actor herself.  Where Sophocles’ Antigone portrayed the downfall of its characters, the new acting focuses instead on the actors.  It requires a commitment to the storyline that cannot waver.  One must literally throw oneself into the role, perhaps through the role, the other side of which is never visible to the world, for the camera cannot see it, which is to say, “into nothingness.”  The actor must agree to become the role until such time as the role becomes her, replaces her.  The new acting is only successful when the actor has come to believe it herself.  Having so perfectly taken on the role, the true nature of the work of art, namely, that it has been constructed, reveals itself by coming to an end.  As with all tragedies, the violence is merely hinted at offstage.  Where the actor might have gone on to do more work, the role must and will come to an end.

Posted in Idea Factory | Leave a comment

Learning to type

Learning to type, when I learned to type, meant learning to become a typist.  The premise on which typing was taught will, for some of you reading this, be foreign; there was a time when typing was a kind of suit that writers put on when it was time to go out into the world.  One wrote in long hand and had work typed as a matter of course, and only at the end.

It’s important enough to repeat: there was once an end to writing, an outside to the writer’s inside, or at least we were taught there was.  Typing was the end of writing.  To type was to focus on something already written, to lock onto it with your eyes, letter by letter, to finger each letter at the keyboard, and to know, more through sound than sight (of course you didn’t look), that you’d faithfully reproduced it on paper.  Typing required all your senses to be engaged together, and to share the work between them:  your gaze focused on the scrawls of pen, your fingers feeling for the key offsets from ‘F’ and ‘J’, your ears detecting the telltale sign of multiple key strikes where only one was expected.  I was taught that writing ceased in typing.  The typist looked into the past, into what was written, not into what was being produced.  Nothing is produced in typing, only reproduced.

Typing today is something quite different.  I’m typing even now, as I contemplate this sentence, as I wander through this thought I hope to write.  The thing I want to say is not yet available.  I have no way to look into it, as though it were somehow solid and approachable.  I’m left to pull it out of what is already before me on the screen.  I have no access to a past that might comfort or control me.  The typewriter has been replaced with the writer.  Writing no longer ends in typing; writing no longer ends.

I’m unclear if they still teach typing.  Is it simply the great prerequisite for all writing today?  I grew up at a time where it still made sense to have both a computer and a typewriter in our house.  They weren’t the same thing, and you’d want both for different tasks.  It wasn’t yet clear, when I learned to type, that only one would be needed going forward.  I learned to type and to write, and it wasn’t yet clear that only one would be needed going forward.

Posted in Digital Swag, Idea Factory | 5 Comments

What I’d do: software teams as indie bands

I’ve often thought that it would be interesting to see software teams do indie band style pictures along with their releases.  I’d like to see the people who write my software.  I know hundreds of people who release libraries and tools, apps, demos and games, drivers and converters and utilities–yet they never really show up.

Long after the death of the album as a physical medium, we still expect to see who made the sounds contained within the music.  They are seated in a semi-circle, posed at different levels, wearing plaid;  they have their backs to one another at the counter of a bar; they are lined up in a wheat field and captured with a hazed filter on the lens; they have neck beards or wear scarves; they want you to notice their glasses and have washed their hair and styled it in order to look like they haven’t;  they do their best not to smile;  they are arranged like the spokes of a wheel as the camera looks down from above on their laughing faces.

When I download version 1.3 of your software, I want an album cover.  I want to feel like I’ve encountered something human, something created.  I want to watch your style change over subsequent releases.  I’d like to see some of what we know as ‘the band’ happen in software.

That’s what I’d do.

Posted in Digital Swag, Idea Factory | 7 Comments

Return early, return often

I’m fixing some code we wrote for the Mouse Lock implementation, based on review comments.  I had forgotten how many of my colleagues teach our students that you should avoid multiple exit points from a function.  It meant that our implementation code had a bunch of deep nesting in order to avoid early returns.  We need to stop teaching that.  There’s nothing wrong with “bailing early.”

Here’s the code in question:

    // When exiting fullscreen, if the pointer is also locked to the fullscreen element,
    // we'll need to unlock it as we the document exits fullscreen.
    nsCOMPtr window = aDocument->GetWindow();
    if (window) {
        nsCOMPtr navigator;
        window->GetNavigator(getter_AddRefs(navigator));
        if (navigator) {
            nsCOMPtr navigatorPointerLock = do_QueryInterface(navigator);
            if (navigatorPointerLock) {
                nsCOMPtr pointer;
                navigatorPointerLock->GetMozPointer(getter_AddRefs(pointer));
                if (pointer) {
                    // Unlock will bail early if not really locked
                    pointer->Unlock();
                }
            }
        }
    }

Here’s how it should look:

  // When exiting fullscreen, if the pointer is also locked to the fullscreen element,
  // we'll need to unlock it as we the document exits fullscreen.
  nsCOMPtr window = aDocument->GetWindow();
  if (!window) {
    return;
  }

  nsCOMPtr navigator;
  window->GetNavigator(getter_AddRefs(navigator));
  if (!navigator) {
    return;
  }

  nsCOMPtr navigatorPointerLock = do_QueryInterface(navigator);
  if (!navigatorPointerLock) {
    return;
  }

  nsCOMPtr pointer;
  navigatorPointerLock->GetMozPointer(getter_AddRefs(pointer));
  if (!pointer) {
    return;
  }

  // Unlock will bail early if not really locked
  pointer->Unlock();

The value of early returns is that it’s easier to read and less likely to contain bugs (i.e., variables can’t change all of a sudden and break algorithm).  If you know that some code path is dead at a particular point, it’s better to return right there.  After you’ve returned, it’s much easier to deal with the remaining code, since you don’t have to worry about hitting this spot due to state changes in a variable.  Plus, it’s way easier to read when you don’t have to visually trace the indenting so far to the right.

Here’s a tip: return early, return often.

Posted in CDOT, Implementing Mouse Lock, Mozilla Education, Seneca, Teaching Open Source | 4 Comments

Occasionals

I write to myself in the future, when I retire, and in case I own a winery, chocolate or cheese shop;  at which time I want to remember to create a line of occasional fare, one very narrowly cast for a particular clientele, those appropriate only for particular occasions, and as gifts for such individuals.

These will want labels, with instructions, that express the intended way and means by which they should be enjoyed.  For example: a bottle of Merlot indicating it is only to be drunk by a person with writer’s block; a box of chocolates that is to be consumed within 4 hours of love making; a bottle of Pinot Grigio that must accompany a summer stroll along a river; a truffle that should be eaten only in sadness, and ideally great sadness; a cheddar so old it must be nibbled while reading a novel of equal age and sharpness.

These ideas I leave here until then.

Posted in Food, Idea Factory | 4 Comments

Holiday Reading

I’m coming to the end of my Christmas holidays.  It has been a very restful and slow time.  I’ve filled it with family, long, slow recipes, and reading.  I logged off irc, closed my mail program, ditched twitter, and allowed myself to become properly isolated from my daily routines.

I also tried an experiment.  My reading tends to follow the paths begun in my literary degrees.  Studying literature causes one to accumulate huge lists of books that need to get read.  I mostly read philosophy, capital ‘L’ literature, and essays.  And I read some of this over the holidays.

But in addition to my usual reading, I game myself permission to venture off the lists.  While in line at the local drugstore I noticed a shelf of books next to the magazines.  Among the paperbacks on the shelf, I recognized two titles.  First, Stieg Larsson’s “The Girl with the Dragon Tattoo,” a book I could remember my brother loving and telling me to read.  Second, Suzanne Collins’ “The Hunger Games.”  I’ve heard various people mention this book, not least my niece and nephew, who were both amazed and horrified I’d never read it, and implored me to correct this oversight.

I found both books nearly impossible to put down, with fast, clever plots.  It was fun to get swept up in dark, unrelenting stories.  The down side of plots this fast is that you don’t linger, don’t need to, the point is what happens next.  I can’t imagine rereading either.

Encountering Larson’s Lisbeth Salander next to Collins’ Katniss Everdeen was interesting.  Both girls (Lisabeth, though an adult, is still very young) have no father, lack a loving relationship with their mother, fend for themselves by breaking the law, and take care of their own safety in ways traditionally left to male characters.  Neither girl lets the world around them into their inner life, and even the narrators struggle to understand much of what is really happening in their heads.  And yet, it’s hard as the reader to not love them both.  It is their very rejection of love that draws so many people to them, makes them so desirable.

Beyond these two strong female characters, the books deal with violence and death, lust (both sexual and otherwise), and power and control.  The books are very different, and intended for different audiences (adult vs. teen).  I found Larson’s repeated graphic rape scenes disturbing and hard to read; though I didn’t find them gratuitous or unnecessary.  However, the novel’s ending was harder to believe than its beginning.  At some point violence piled on violence isn’t achieving more, but begins to create a landscape where such things are common enough that they must be accepted or ignored.  Collins, on the other hand, intentionally creates such a landscape, where children killing children is simply good television.  Her presentation of the Capitol, and its mostly unseen populace, is haunting in what it doesn’t reveal about this acceptance.  Who are these people who take such pleasure in such horror and pain?  Larsson wants us to understand that they are the people we least expect, the people who are most completely unlike what we expect.

Friendship plays a central role in both books.  For Larsson, the word is sometimes used as a euphemism, sometimes as a threat, and often as an impossibility.  Lisabeth and Katniss are both right to distrust the people around them, both so well practiced at it that the impossibility of real friendship is really the point.  Neither book affords its character the chance for anything more than temporary agreements: friendship as deep relationship is simply not available in either of Collins’ or Larsson’s worlds.

Reading the books also put me in mind of other similar books I’ve read, especially in the case of “The Hunger Games.”  In the first third of this novel I was repeatedly taken back to Herman Hesse’s “The Glass Bead Game,” a book so incredibly different in many ways, but eerily similar in others, especially in its narrative of children being taken from their families and trained for games that the rest of the society will witness.  The latter part of the book echoed Tom Brown’s “The Tracker.”  The scenes with Katniss caught up trees, hunting, and tracking through the woods were very well done.

Both books are first in a trilogy.  I don’t think I want to continue in Larsson’s world.  The first book was gripping, horrifying, and stands on its own.  Much as I feel about the evil in Charles Williams‘ novels, I understand its point in the story, but don’t want to subject myself to more of it than necessary.  I will likely read the next Hunger Games book, though.  I thought that there was much left to do in that story, and I’m interested to see how Collins will manage it.

Will I continue to read using the drugstore as my guide?  I’m not sure I will.  However, I loved this holiday from my usual patterns of reading.

Posted in Reading | 3 Comments