CS312 - Spring 2012 - Class 16
admin
- please read through the final project handout so you know what is expected and when
- during tech talks, the only thing you should be using the computers for is taking notes
projects
- I understand that the first sprint is tricky to get up to speed, get used to the group, etc.
- If you're still struggling come talk to me ASAP
- Finding work:
- it is the groups responsibility to define the user stories
- it is your responsibility to make sure you know what you're doing and that you have something to work on
- stand-up meetings
- you are required to attend every stand-up meeting
- if you cannot be there you must e-mail the team BEFORE the meeting and include your contribution and why you were not there
- if someone does not show up or e-mail, please have someone on the team e-mail me
visual debuggers
- using print statements can help you find simple bugs
- for more complicated bugs:
- they're time consuming to put in (and to remove)
- you may not know where the bug is
- for loops, etc. you may not want to see all the values printed out so have to add conditionals
- for complicated data structures, sometimes it's infeasible to print out the data structure
- a better approach is to use a debugger!
Eclipse debugger
- many IDEs (integrated development environments) have a debuggers
- they are MUCH more user friendly than gdb or other command-line debuggers
- many programming languages have a suitable IDE with a built-in debugger
- today, we'll use look at the Eclipse debugger with java, but many of the concepts are the same for other IDEs
look at DebugExamples.java in
DebugExample code
- to set a breakpoint, you right click in the left-most column of the editor window and then select "Toggle Breakpoint"
- when run in normal mode, these breakpoints don't affect anything
- when run in debug mode, when the program reaches a debug point it stops and enters the debug view
- for example, we can set a breakpoint at the "int sum = 0" line in example1
- if we run this method in normal mode, the method runs normally
- if we run it in debug mode, though, the program stops at the breakpoint
debug view
- the debug view in eclipse has a number of windows
- the bottom left is the code and the current line the program is waiting to execute is highlighted
- in the bottom right, is the general code outline (with the function that you're in highlighted)
- the upper right has any variables in your current context (right now, none)
- the upper left is the run-time stack (more on this in a bit)
- notice that there are two things on the stack right now: the call to main and the call to example1
- we can move the program forward in a number of different ways:
- step into (F5 or use arrows above): jumps into the current function call (if applicable)
- step over (F6 or use arrows above): execute the current statement and moves on to the next line
- step out (F7): finished executing the current method and stops wherever this method was called
- the red square stops the program
- the green arrow (next to the red square) runs until the next breakpoint is hit
- as we step through (F6) we can see the debug environment change
- sum shows up in the variable with its value
- i eventually shows up
- i and sum get updated as we step through
- if we get tired of stepping through the for loop, we could either:
- set another breakpoint at the system.out line and then hit the green arrow
- or hit F7 to step out of the function
conditional breakpoints
- let's say we wanted to follow the progress of the for-loop, but we ran it now for 1000 rather than 10
- we'd like to check in on it periodically (i.e. we don't need to see all values)
- one way would be to add an if statement inside the loop and then put the breakpoint inside the if
- but then we'd have to delete this code later
- we can edit the properties of the breakpoint to do this
- right-click on the breakpoint and select "breakpoint properties"
- the "Hit count" box allows you to have this breakpoint stop the program not every time but when it has been hit some number of times
- for example, if we set it at 100, it will stop every 100th time it's passed over
- this fits many situation, however, sometimes you want to define when the breakpoint will stop
- in the same menu, there is a "Conditional" field you can edit
- you write a statement that must return true or false based on the current variables
- if the statement returns true, the breakpoint will stop
- if the statement returns false, the breakpoint won't stop
- for example, we could enter: "return i % 100 == 0" and it would stop every time i was divisible by 100
changing variables on the fly
- if you want to change the value of a variable when the program is executing you can :)
- right-click on the variable and select "Change value..." and then enter a new value for the variable
- when the program continues running, it will use this value instead of the original
look at linkedListExample in
DebugExample code
- we can set a breakpoint at the constructor call in the linked list
- if we step over that call we see the linked list variable in the variable lists
- if we click on the arrow to the left, we can look at the private instance variable that make up the object
- right now it's empty so head is null
- if we step over through a few lines of the for loop, though we can see that the linked list gets populated
- for recursive data structures, you can continue to dial dive into the variable to follow the links
- lets say we'd like to see the functionality of the add function working
- when the line is over the "l.add(i)" line, we can "step in" to this function call using F5
- this jumps us into the linked list code and now we can continue to walk through the code
- when we're done, we can "step out" of the function using F7 which will take us back into our DebugExample class
look at factorial in
DebugExample code
- this is a basic recursive definition of factorial
- we can set a breakpoint at the if statement and then watch the function execute
- as we step through you can see the if statement getting evaluated
- when we get to the recursive call, we try and step over the recursive call we're going to hit the breakpoint again
- notice that now n = 9
- we can just hit the green run arrow to run through another recursive call if we'd like
- notice how n = 8 now
- the run-time stack is shown in the upper left hand corner
- at the bottom is the call to main
- then the call to factorialExample
- then the first call to factorial
- then the next call to factorial
- etc.
- each run-time stack has all the information of the stack-frame and we click on any one to see it
- notice that as we click on the different stack frames the variables change
- the line that it's current waiting on/executing changes and is highlighted (this is also indicated by the line number to the right of the call-stack)
- eventually, if we run through enough iterations then the base case will be hit and we will return from each of the recursive calls with our answer
your turn: look at the BugFinder class in
DebugExample code
- there are four different test examples called in the main method (one on the ArrayHelper class and one on the LinkedList class)
- run the examples and see which ones work and which ones don't
- for the ones that fail (i.e. that don't print out appropriate values)
- take a quick look at the code in the corresponding classes and see if you can figure out why it's failing
- if you can, great!, but I'd still like you to practice using the debugger to find them as well :)
- set some breakpoints and use the debugger to try and figure out where the problem is happening is why