2005-10-14

Nopey saves the day

Ever been bitten by your bad habit of writing something lengthy into a browser, just to have the browser become unresponsive, and, in effect, hang up on you so you can't even copy and paste the text somewhere safe? I'm still doing it, way too often, and certainly often enough to also get bitten by it once in a while. Today I had about an hour's worth of writeup hung on me just like that, in a run-havoc Firefox 1.5 beta 1 process. (I don't think firefox is to blame, though; I've started suspecting faulty memory. Time for a session with Memtest86 to verify.)

It was only the firefox process gone mad, though (and the nView requester wondering if it should stop monitoring the unresponsive process to avoid becoming unresponsive :-), so I could still fire up a Competing Browser for some help, so I asked the oracle for windows dump process memory to disk, and was rewarded with Nopey. Nifty little tool, that; it certainly did save my day, quite literally. Fire up a command prompt (Windows+r, cmd, enter), drag the nifty binary there, add a " dump firefox.exe" to that, and watch the directory crowd up with a busload of dump files.

Then I fired up an interactive Pike session, Pike being my language of choice for any heavy hands-on kind of work like this, picked a large US-ASCII-only word I knew I had typed in there, and made a quick grep through the files for this string. It went a little like this:

Pike v7.6 release 24 running Hilfe v3.5 (Incremental Pike Frontend)
> array d=filter(get_dir("."), has_prefix("firefox"));
> array r=map(d, Stdio.read_file);
> string needle="utbildnings";
> search(map(r,has_value,needle), 1);
(1) Result: -1
>

Nope, no go. But I actually rather expected it to be stored internally as some form of more or less perverted unicode format, probably in UCS-2 or perhaps UCS-4. Which, for US-ASCII would mean putting every character in a 2 or 4 bytes long word, the other bytes zeroed out. Trying UCS-2 first, I added an ASCII zero between each character (that way endianness won't matter), and tried again:

> needle=needle/1 * "\0";
(2) Result: "u\0t\0b\0i\0l\0d\0n\0i\0n\0g\0s"
> search(map(r,has_value,needle), 1);
(3) Result: 191
> d[191];
(4) Result: "firefox.exe_075A0000.dump"
> file_stat(_);
(5) Result: Stat(-rw-rw-rw- 294912b)
> search(r[191],needle);
(6) Result: 150798
>

And behold! There it is, in all its glory. (Had it been UCS-4, I would have simply arrowed back to the top statement above, adding another zero byte between every octet in the needle, making it u\0\0\0t\0\0\0b[...] -- but now I obviously didn't have to.) Next, I fired up Emacs for a closer look at this region. C-x C-f firefox.exe_075A0000.dump <enter> C-u 150798 C-f, and we're in the middle of what looks very much like my note with lots of interspersed ^@ markers. Yay! C-e C-<space> C-a M-% C-q 000 <enter> <enter> ! C-a, and we're back with what looks even more like my note, though partially URL coded (good thing I picked a US-ASCII word; even spaces were coded as ugly %20s). I copy the line to a new buffer, tidy it up a bit around the edges (where there is some junk) and save it to a file of its own for final post-processing: C-a C-<space> C-e M-w C-x b lazarus.txt <enter> C-y C-x C-s <enter>, and switch back to my Pike window:

> string x=Stdio.read_file("lazarus.txt");
> write( Protocols.HTTP.Server.http_decode_string(x) );

...and out pours my precious post, as it was meant to look. Yay!

I stow it away in a safe place, and write up this, in the hope of perhaps helping some other poor soul in a bit of a bind. I wonder what tool would have fit the Nopey part of this tutorial in a linux context; last time I was really bothered by this problem was a time when I did not have today's good google karma. Suggestions?
Categories:
blog comments powered by Disqus