Wandering Thoughts archives

2007-03-31

A simple debugger feature that I would really like

Following up on my earlier thoughts about print based debugging, here's an easy debugger feature that would make my life much better (and make me more inclined to actually use debuggers):

Provide a way to record things that doesn't show them to me until I ask for them.

I'm not actually interested in reading the things that I print out, not right away; I'm just collecting the information so that I can look back in time at the program's state once the bug strikes. The only reason I'm printing things out is that this is the only decent way debuggers give me to dump information for later perusal.

Thus, hiding the stuff that I want to record until I actually ask for it is a big net win, because it avoids drowning me in output that I'm just going to ignore until later anyways. As a bonus the debugger would probably run faster because it doesn't have to display and scroll all that text.

This more or less requires a graphical debugger with some sort of scrollback buffer, but it should be an easy feature to implement. Pretty much everything has a 'print something at a breakpoint' feature, and once you have a scrollback buffer it ought to be relatively trivial to insert content into the scrollback area without actually putting it on the screen.

A debugger would get bonus points for making the record searchable, and more bonus points for being able to directly snapshot the state of variables and the like rather than just saving text output. (This might also make the data take up less memory. You do want to provide for journaling text, since sometimes that's the best way summarizing some bit of state.)

SimpleDebuggerFeature written at 01:39:35; Add Comment

2007-03-08

A bad popup dialog

Imagine this: you click a directory folder in the desktop browser to open it up, and a popup dialog appears that says:

Opening 'Something'.
You can cancel this operation
by clicking cancel.

                       <CANCEL>

(The <CANCEL> is a dialog button, the only one in the dialog.)

Quick! What happens when you click the cancel button? Are you canceling the annoying popup, or the operation that you wanted to actually do? What is the safe thing to do? Really, I have no idea what the designer of this dialog was thinking.

(Bear in mind that users (myself included) have been conditioned to just click on 'cancel' buttons to make annoying dialogs go away.)

What makes this worse is that it was written well after the invention and widespread popularity of the web browser, which has given everyone a well known and familiar interface for canceling opening something when it is taking too long, and is happening in a browser-like window that already goes backwards and forwards. So they stole part of the browser interface, but not enough of it.

I have to wonder how this got approved, and if anyone at all used it before the code shipped.

(This dialog is courtesy of Solaris 10's default desktop environment, to give credit where credit is due.)

BadPopupDialog written at 19:49:34; Add Comment

2007-03-01

An irritating limitation of listening sockets

Traditional sockets implementations have an irritating limitation, at least for TCP sockets: it is impossible to gracefully and cleanly shut down listening (server) sockets. The problem is that kernels accept new TCP connections for listening sockets without asking your server; accept() doesn't actually accept the connection, it just gives you the next one that the kernel has already accepted on your behalf.

This means that to shut down cleanly, you need a two-stage process: first you tell the kernel to stop accepting new connections for you, and then you process all of the existing accepted connections. If you simply dump everything, clients will see abrupt disconnections of established connections, because from their perspective the connection is complete; their connect() finished, and they can even have been sending data.

Unfortunately, there's no two-stage close interface for server sockets (at least, none that I can see):

  • if you just close() the socket, you flush the pending accept() queue.
  • you can't un-listen() by setting the backlog size to 0 or -1 or the like.
  • shutdown() is either the same as close(), does nothing, or produces very peculiar results, depending on the system and the exact arguments; in no case does it cause further connect() calls from clients to be refused.
  • SO_ACCEPTCONN is a read-only socket option.

(You can do this with Unix domain sockets, by removing the socket file itself without closing your server socket fd.)

Among other consequences, this means that protocols where the client connections and immediately starts sending data are dangerous; the client had better be prepared for the entire conversation to fail. The only way to make sure that the server is really there (instead of in the process of shutting down) is to wait for it to send you something, which may be why so many Internet protocols start with greeting banners from the server.

(As a pragmatic matter the server can lower the risk by not closing things down until accept() on a non-blocking socket returns an error, but there's still a concurrency race, just a smaller one.)

SocketListenLimitation written at 23:36:41; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.