• Aucun résultat trouvé

Using Notifiers and Debuggers

Dans le document The Art and Science of Smalltalk (Page 186-189)

Probably the first thing you'll know about a bug in your code is that you get a notifier window popping up. Smalltalk notifiers are popped up in response to exceptions, which arise in 'exceptional' circumstances such as the system not knowing how to deal with a particular message expression. The diagram on the next page shows a couple of notifiers.

In line with the general principles we've just looked at, the first thing you should do is to stop and look at the notifier—don't just close it. Smalltalk notifiers give quite a lot of useful information. Obviously, you get the name of the exception ('Message not understood', 'Division by zero', etc.). You also get a stack back-trace which shows you exactly what was happening up to the time the exception occurred.

Each line in the back-trace shows a message being sent, starting at the bottom and working up to the top where the error occurred. On every line you'll see the name of the class of the object which received

Chapter 15

Notifiers from VisualWorks 2.0 (front) and an earlier version of Smalltalk (behind). Both were generated when the system realised that nil doesn't understand the message

wibble.

the message, then the name of its superclass which actually implements the method (in parentheses), and then the method selector itself (after the »). In other words, each line looks like this:

Receiver-Class (Imp lementorC lass) »mes sage Select or

The very top thing on the stack back-trace will be Smalltalk raising the exception (yes, you actually get to see the code which generated the error message!). This means that you're almost always interested in the second line down. This is where the immediate cause of the error is.

The back-trace will tell you the name of the method in which the error occurred, or unboundMethod if the error happened during a do it, print it, or inspect.

Underneath the second line down are all the messages on the stack leading up to the error. Remember that you are looking at a call-stack.

This means messages which were sent prior to the exception, but which have already returned, won't be visible to you here (even though they may be the ultimate cause of the bug).

The other thing to remember is that Smalltalk doesn't make any distinction between 'its' code and 'your' code. They are one and the same as far as the system is concerned. This means that the stack back-trace could easily consist of a mixture of your code and code from the class library. So, don't be concerned if you don't recognise all the code that's being shown to you. The diagram on the next page shows a couple of examples of this phenomenon.

Debugging Smalltalk Code

Two possible combinations of your code and the system's code in a stack back-trace.

As you will see, you may be presented with a stack in which a fair bit of system code leads up to your code starting to run, with the exception happening in your code. This is especially true of exceptions resulting from do its in a workspace.

The other situation is where your code invokes some method in the class library, which then invokes a potentially large number of other methods in the class library, before the exception eventually occurs in a system method. This doesn't mean you've found a system bug! Instead, it means you've done something in your code which led to a problem which wasn't detected until the system eventually tried to do something forbidden in its own code (like access an element which isn't present in a Collection).

After you've looked at the error message and the stack, the next thing to do is to decide whether you need to open a debugger.

Depending on the version of Smalltalk you have, you'll be given the choice to do this either through a pop-up menu, or through push buttons. If you think you know what the cause of the problem is, that's fine. Just close the notifier and go and fix it. If you want to take a closer look at the code that caused the error, examine variables and have the chance to modify the code, then you should open a debugger.

If you decide to open a debugger, make it big. You're trying to get a view on what's gone wrong, so there's no point squinting at your code through a tiny little window (sometimes the default sizes at which Smalltalk opens its windows are ridiculously small. We covered the basic use of debuggers in The Science of Smalltalk, and it's also covered in the manual. The important thing is to make sure you make full use of the facilities you're given.

You can browse up and down the stack looking at the path the system took through your code. If there's not enough stack for you, you

Chapter 15

can ask for more via the operate menu in the stack pane. Remember that just like in the notifier you could be looking at a mixture of your code and the system's code. If you see system code at the top of the stack, it's worth scrolling down (back in time) to see where your code begins. The interface between your code and the system's is the last chance your code had not to generate an error. This is often where the bug is. Remember though, that your code could have generated the error much earlier (either in the call-stack or outside), with your code happily passing on a bad object until an exception eventually gets raised much later. If the method which actually has the bug in it has already returned you won't be able to see it in the call-stack. In this case you'll have to interrupt your code and follow it through manually to find the bug. We'll look at how to do this very shortly.

You can use the two embedded inspectors at the bottom of the debugger to look at the state of instance variables, as well as temporary variables and parameters to methods. Remember that you can also execute code in inspectors. If you want to test out how an object responds to a message, make sure one of the inspectors is inspecting it, type an expression, select it and evaluate it.

If you think you can see the source of the problem, you can use the code pane of the debugger just like a browser. You can edit the code and accept it. Be careful though, because if you've got another browser open on the method, and you subsequently go back to using that, you'll put the error straight back into your code! This occurs because browsers do not automatically update themselves when the code they're browsing is changed elsewhere.

Dans le document The Art and Science of Smalltalk (Page 186-189)