Ken Orr: My name is Ken Orr.
I work on the Debugger User Interface Team.
And this morning, I'm excited to be able to show you the new Debugger UI in Xcode 4.
Before we do that, before we jump in, I want to talk a little bit about the motivation.
So Debugging is really central to what we do as developers everyday.
I want you to take a second, and I want you to think about just how much time you spend each day debugging.
So go ahead and think about that.
Maybe it's 50 percent, perhaps even more.
And that's why it's so important that we provide you with a really great debugging user experience.
And that's what we've tried to do with Xcode 4.
And a few things we focused on to make that happen are first, the workflow.
So that means putting the user interface that you need in the right place at the right time.
So we want the UI to fade into background so that what you're doing is what you're focusing on.
So you don't have to worry about the UI.
That's the first thing, probably the most important thing.
Secondly, there's a lot of information there when you're debugging, variables, threads, all these things, all this information that we have to process.
And to make it easier to process that information all throughout Xcode 4, you're going to see things like Filter Bars, Scoping Bars, so that you can drill all the way down into the details that you need without seeing the information that you don't need to see, and then you can back right back out really quickly.
So you'll see that all throughout Xcode 4.
And also, especially for debugging, we live in a multithreaded world.
So all of our apps are multithreaded, you need to be able to debug a multithreaded app.
So it was important that we built in support for multithreadedness from the ground up.
And we've done that all the way down at LLDB, up through the UI, and we'll see a couple of examples of that as we go through the UI this morning.
So let's dive right in.
First we're going to go over, we're going to give you a high level view of Xcode 4, what it looks like when you're running it for the first time, and then we're going to go in and we're going to focus on each of the components in the debugging workflow, and we'll talk about the pieces of those UI components.
So here is Xcode 4.
This is what it's going to look like the first time you open it up.
So you'll see on the left side here, that's what we call the Navigator area.
By default, you'll see the Project Navigator that shows all the files that are in your project.
In the center right area, that's the Editor area.
So that has your source code.
It's the focus of what you're doing, the focus of your work.
So now, when you are when you're ready to run for the first time, you're going to look up to the top left, and you're going to click that Play button, straight forward.
And when you do that, this is what Xcode's going to look like.
OK, so what changed here?
Well, if you look down towards the bottom of the UI, you'll see that the Debugger Bar popped in to view.
So the Debugger Bar will show up anytime you're running.
So it's kind of your visual cue to say, "OK, we're running now."
And if you look towards the left side of that component, you'll see this little upward facing arrow with some color behind it, and that's the button you clicked to expand the Debugger area.
But what that little icon tells you, by being colored like it is, is it says, "You have consult output waiting for you that you haven't read yet."
And this is a nice little affordance to indicate that information to you without actually disturbing what you're doing.
So we won't interrupt you and pop the UI up and show you that.
we'll just kind of gently hint it.
And that's what that button does.
Now, if we move more towards to the right here, we'll bump into the thread stepping controls.
Not much new there, we've had thread stepping controls in Xcode 3.
But what we've added in Xcode 4 is a couple of new ways to step through your code.
So if you hold down the Control button and you click one of these thread stepping controls, you can step by a single instruction.
But what's more interesting is if you hold down the Shift button and the Control button and click, that will let you step by that will let you step and suspend all the other threads.
Now, why do you want to do that?
Well, you might not know, but when you normally step sometimes all the other threads are given a chance to run.
And we do that to prevent deadlocks and various things.
So what can happen is if one of those threads has a breakpoint, it hits a breakpoint, you can be context-switched to that other file, and that can be very jarring, very confusing, it's not always clear what happened and why it happened.
So if you're in a situation where you know you just want to step in a single thread, you want to prevent anybody else from running, you can now do that in Xcode 4, really powerful way to debug.
So we've started up our app.
And now, we're ready to set a breakpoint for the first time.
Not much has changed here since Xcode 3.
You can see that we just click in the Source Code Editor Margin, like we've always done.
But you'll also notice this button here in the top tool bar area has toggled down.
That button is the Breakpoints Activated button.
That lets you quickly activate or deactivate all your breakpoints.
So you're debugging along maybe for a couple of hours, you're setting breakpoints, you're tweaking it, trying to find out what's going wrong.
You finally get to the point where you think, "OK, I've solved this problem."
and you want to deactivate all of your breakpoints.
Now, you don't want to have to go through and disable each breakpoint.
You want to be able to have a big switch to do that.
And in Xcode 4, we have that, and that's this Breakpoints Activated button.
So we've set our breakpoint, we've done something in our application, we've hit the breakpoint, and now, we've stopped edit here in the Source Code Editor.
So let's take a quick look at what happened in Xcode when we hit that breakpoint.
The first thing to notice is that when you hit a breakpoint you'll be automatically switched to the Debug Navigator.
We'll talk about the Debug Navigator in the minute in more detail.
And a little bit later on, we'll show how you can change what happens when certain Xcode events occur in the system.
But just know by default, when you hit a breakpoint, you'll be switched to the Debug Navigator.
Also, you'll see that the Debug area has slid into view.
So the Debug area shows us our variables, and it shows us the consoles, the console output.
[ Pause ]
OK. So now, we've made debugging for a while, we've set some breakpoints, and we're ready to kind of manage our breakpoints in a little bit more detail.
It's convenient to do that using the new Breakpoint Navigator.
And you can see that's the navigator with that little Breakpoint button on it.
This shows you all your breakpoints grouped together, you can see them all in one nice, neat place, and again, we'll talk about that one in a little more detail in the minute.
So let's dive down, that's kind of the whirlwind tour of Xcode 4 and what it'll look like the first time you debug.
But let's look in detail at each of these components.
So here's the Debug Navigator that we saw a minute ago, and the Debug Navigator shows you all the threads that are active at a current line of code when you stop.
So you stop at a line of code, this will show you all the threads that are existing at that moment and time.
So you have a couple different ways that you can look at that information.
You can look at that information grouped by queue, so we're seeing that here, we're seeing it grouped by Grand Central Dispatch queue.
So a thread will be put in its GCD bucket.
So that can be a really useful way to look at things if have a if you're using GCD in your application.
You can also look at things just by threads.
So you can kind of flatten out the list a little bit more and just see a group by thread.
Now, you won't actually lose the GCD information.
If you look underneath the thread name, you'll see another little subtitle there, that's actually the Grand Central Dispatch queue name.
So you can still see that information, but we've kind of lost a little bit of the hierarchy, and that can be useful sometimes as well.
So this is great.
We have all of our threads here, we can see them all now at the same time.
But sometimes, this list can get really, really long.
And I don't have great attentions span, so I need to I need the UI to help and get rid of things that maybe don't matter to my debugging task.
And in Xcode 4, we've added a bunch of different ways to help you focus in on the information that you need to see right now.
So the first thing we have here is we have this Thread Filter button.
So a lot of times, you're going to have Threads that show up in this view and it's going to have stack frames, none of which you have debug symbols for.
You know, there are System Threads there.
They're not really relevant to what your debugging, and thechances that there's any problems in there that you are looking for actively are not good.
So we can go ahead and we can click that button, and we can get rid of all those threads.
So that's great.
We've really narrowed down what we have to look at here.
So that's the first really nice thing.
Now, that's great, but we can do even better.
We can get rid of stack frames that we don't have debug symbols for.
So we have a thread, it has a whole bunch of stack frames in it, some of them are ours.
So that's code that's our code, we can debug into it.
But a lot of the stack frames of app kits calling into you, maybe you don't always need to see that information.
And as you use this little filter scrubber here, you can you could of course, scrub it all the way to the right.
That means show me as much details as there is.
So to fill you all the stack frames that exists.
But you probably don't need that much detail.
So as you scrub to the left, we'll start taking away stuff.
So in the midpoint here, we're showing you your stack frames with a little bit of context around that.
So we're showing you some of the system stack frame that you don't have debug symbols for, but you can get even less detail if you want that, by scrubbing all the way to the left.
And that will show you only stack frame zero, and that can be useful sometimes as well.
[ Applause ]
So these are two really nice ways to kind of really drill down into the information you need for what you're debugging, and it's really easy to toggle between different views.
So let's take a little bit deeper look at the Breakpoint Navigator.
So the Breakpoint Navigator shows you all the breakpoints you have set in your project, and it shows you those breakpoints grouped by file.
As you can see here, all the File Breakpoints are listed first.
And then underneath those, we list the Symbolic Breakpoints, followed by the Exception Breakpoints.
The Breakpoint Navigator is a really convenient way to go through and disable or enable breakpoints because you can see them all at once, and you just click on the little Breakpoint icon, it's that little blue icon there, to disable it or enable it.
Really, really handy.
The Breakpoint Navigator's also the place where you go when you want to edit a breakpoint's its details.
So here, we've double clicked on a File Breakpoint, and we see this little Pop-Up Editor show up.
So that's the file Breakpoint's Pop-Up Editor.
So in that editor, we can do things like change the enablement, we can set the condition, set the ignore account, could also add actions.
So we can do things like print a variable out, we can play a sound, we can run an AppleScript, we can do all sorts of things.
That's really powerful.
In conjunction with the actions, you can do this thing where you automatically continue after actions are run.
Why would you want to automatically continue after the actions are run?
Aren't breakpoints meant so that you can just stop and introspect and look at your code, look at your state?
Well, it turns out you can print out a variable and automatically continue, and essentially put a print out in your code without actually putting a print out in your code.
That's another really powerful technique that you can use to debug your apps.
Now, down here at the bottom of the UI, we'll see this the ability to add Exception Breakpoints, and also Symbolic Breakpoints.
So you can do this all right from the Breakpoint Navigator now, which is very convenient.
If we take a quick look at the Pop-Up Editors, so the Exception type Breakpoint has it own custom Pop-Up Editor where you can change the kind of exception.
So by default, you're going to stop in all exceptions.
But if you just want to stop on Objective-C exceptions, you can do that.
Or if you want to just stop on C++ exceptions, you can specify that.
You can also specify whether we break when the exception is thrown versus whether-when it's caught.
So you have that choice as well.
And you could also add actions to these breakpoints just like you can with file type breakpoints.
Here's what the Symbolic Breakpoint Pop-Up Editor looks like.
So you can put a function name in, you don't have to know where that function is, we'll just stop anytime that function is called.
This is a really nice type of breakpoint to use in some cases.
OK. So we've got I got that overview, a flavor of what these components look like.
Now, Hahn Ming is going to give us a great demo of those components in action.
[ Applause ]
Hahn Ming Wong: Hi there.
My name is Hahn Ming Wong.
I'm one of Debugger UI Engineers.
So a few words about the demo I'm going to do next.
If you have been to our previous WWDC sessions, debugging sessions, usually, we take a project, it has a bug in it, or rather, we introduce a bug in it, and then we bring to bear all of Xcode Debugging Tools, and then we solve it, and all of you will applause, and there would be world peace.
But there will no world peace today.
Not in my demo.
Because we think Xcode 4 is so full of new, you know, debugging UI and gestures that we think it's worth while to showcase to you the last two things that Ken mentioned, so that when you play with it on your laptop, on your flight back home today, or you know, later on in the lab, you'll have a better idea on how it works.
I'm going to bring up the target.
Whenever I refer to the target, although inferior, because he is so superior, but the target is the application that is under the debugging session.
And surprise to say, today we're looking mipmap.
You may have seen this in other demo sessions.
It is an application that takes in a lot of large images and shrink them down into small images.
So I'm going to bring up the preferences.
And you can see, what it does is it makes use of eitherGCD or pthreads, you know, the two systems of threads on Mac OS X, and in this case, I'm choosing pthreads first, and I'm going to make use of two course together where the scaling image work done.
So let's go back to Xcode 4 now, and let's bring up the Breakpoints Navigator that Ken talked about.
Here, we have I already have two breakpoints that I set early on that's disabled.
So the Breakpoints Navigator is a central place where you come and manage all the breakpoints that you have set early on, or going to set next.
For some of you breakpoints collectors out there, this is the place that you will visit quite often.
So a navigator well, being a navigator, when you click on it, will bring up the source code for this breakpoint and scroll to that line so that, you know, you're sure you are breaking at the right line.
So you know, when you double-click on that, it brings out the editor, the little window for you to set conditions and what not.
My favorite feature here is the fact that I can easily set an Exception Breakpoint.
In Xcode 3, you have to go through a couple of places.
Now, you know, OK, the first time is activating it, OK, great.
There you go.
Right. And setting the Exception Breakpoint is really important, at least for me, because when there's Exception in your application, there is a problem, and you want to catch it live because you have live stack frames for you to poke at, you know, variables for you to explore.
So I really encourage you to just set it on and leave it there, and this is what we're going to do for the demo.
Next thing-=-and we're almost ready to debug.
So I'm going to enable this breakpoint right here by either clicking on the icon here, or I can do it in the gutter, just like what you can do in Xcode 3.
OK. Let's go back to the target and I'm going to start.
I can see that, like Ken mentioned, the Debug Navigator is showing now, and I want you to well, I want you to focus on the Debug Navigator while I run a continue a couple of times, so that I get a feel of what this multithreaded application is doing.
It looks like it's sometimes alternating between Thread 7 and Thread 8, and sometimes doing it twice in one of the threads.
This is Multithreaded Debug application running.
So a little bit of it or a lot of it is unpredictable.
So we are capturing a snapshot of it and giving you a live view of it.
Let's see what I can get into a state where sometimes, it will maybe not.
OK. Sometimes, what happen is it will stop in Thread 8 twice.
And in the Editor, you'll see a little annotation like the numbers of threads that are now currently stopped in this Breakpoint.
Again, we take a snapshot of it.
I cannot control what the computer does, so you know.
So again Thread 7 and Thread 8 are showing.
Now, if you remember, Xcode 3, those of you who's have been using for a little while, there's a little pop-up there, and you have to enumerate through each of the threads and show the stack frames.
By the time you're looking at thread frame 1, you forgot what thread sorry.
Thread 1, you forgot what Thread 8, you know, is doing.
Here, we're giving you everything so you can look at it.
However, because we are giving you a lot of stuff, you know, some of you were comfortable with drinking water out of a fire hydrant, more power to you.
But the truth is, you know, some of these stack frames may not be that useful to you right now because you're trying to figure out why this thing is not working well.
Again, if you can read this, I hope, like a book, you know, you're great, but I prefer to focus on my own code.
So again, I'm going to switch back to Thread 7, the stack frame zero to stack frame 7, these are system frameworks code.
So that's why we have some filters at the bottom here that can help you out with that.
The first one is the Stack Frame Compression Filter, and it is now, it is scrubbed all the way to the right.
It means, it's showing you everything.
But you start scrubbing to the left, we start compressing based on setting heuristics.
If you have feedback on the heuristics, follow and ends when request, and we'll look at it.
So we can see that zero to seven have been compressed down.
Now, those of you who are doing UIKit or AppKit, sometimes, the compression could be really great because it's from one to, you know, 80.
We still show you the entry and the exit frame to give you in a context.
And now, we are left with your code.
The reason why it's your code is because there's a batch showing with your face on it, so and then the project is the source code is a file in a workspace.
OK, and the other button, Filter Button is the Thread Filter button.
I'm going to toggle and untoggle it.
And again, pay attention to the Debug Navigator.
It looks like Thread 2 disappears, and if we open it OK.
So this is the libdispatch-manager thread.
So unless you are a libdispatch engineer, you're probably not too interested in that.
So we usually sorry.
In this case, so we when you toggle, the Thread Filter button is gone.
So we can see that while we're presenting you more information, we are presenting you a concise view of it.
A little oxymoronic, but if you play with it, I think you'll appreciate how it actually works.
I'm going to go back to the Breakpoint Navigator and disable the breakpoint.
I'll continue and go back to the Target Application.
Because the next thing I want to do is to make use of GCD.
This is not a GCD session, so I won't get too deep into it, but essentially, it is a very elastic way of helping you with a multithreaded job.
It spawns off as many threads as it thinks when the system is not under a load, so that in this case, it will help you with your scaling image work.
I'm going to switch I'll limit it on currency.
So we enable the breakpoint, and let's switch back to the target and start.
So a similar thing will happen, if you like it, I'll stop.
OK. I'm going to again, I'm going to run well, let me show all threads, All right.
I'm going to run a few times, so that you have a feel of it.
The thing about GCD again, you can see it's spawning more and more threads because I'm not running iTunes, I'm not running Flash and Safari.
So the system is OK.
I'm just doing demo.
So you know, it's spawning more and more threads to help with me my work.
But as you can see when I'm working GCD, when I have more threads, there's a lot more information coming in which is why we think when you're working with GCD, if you look at it by queue view, it may help you a little bit more because we organized the threads into queues.
We put them into queues.
Let's look at quickly look at some of the queues.
This is the main queue, named the Main Thread, and this is Dispatch Manager Queue, and there are two concurrent queues that are being used right now.
GCD has three concurrent queues; the high priority, the default priority, and the low priority.
The default priority has one thread, and this just happens to be the Image Processor Controller Thread that is in the default queue, and the developer of this application is pretty smart to put all the scaling work into the low priority queue.
So we can see that and then we have a thread over here.
What that just means is this thread let's look at it actually.
OK. It's just a worker thread has been spawned off, but it has not been put into one of the queues.
If you toggle this button, it will go away because it's not interesting.
And with that, I'm going to hand you back to Ken.
Ken Orr: Great.
So let's a take a quick tour of the Variables View now.
Here's what it looks like, and of course, it shows us all our variables that are available on a current line of code.
So by default, you're going to see all the variables in local scope.
Now, that can be a rather long list.
So here, it's pretty long, but it can get a lot worse than this.
And like I said before, I want the UI to help me see what it is I need to see.
And in Xcode 4, we can do that by using this new View Mode.
So, if you look up here, we have this View Mode, and you can toggle that to auto.
And what Xcode is going to do is it's going to say, "OK.
Here's the line of code you stopped at.
What are the variables around that line of code?"
It's just going to look before, it's going to look after, and it's going to figure out which things are changing.
And so, probably, those are the things that you need to see right now.
And so, that helps us whittle down this list a little bit.
And that's great.
And so, we still have 6 things here.
We can probably do better if we jump over here and use the filter bar.
So as you might guess, the filter bar, you can type a variable name, and of course, that will filter out everything without that variable name.
But what's more powerful about the Variables View here in the filter bar is that you can actually type in a variable value.
So I've typed in document.graphics, and it turns out that these two variables have that in their value.
So this is a very powerful way to look into your variables.
Also, the Variables View is the launching point for the new Memory Browser.
So the Memory Browser has a completely new UI, and you can get to it by right-clicking on a variable, and then you go down and select view memory, and that will take us here.
So we'll see the new Memory Browser open up in the editor area.
So that's that central area where you're working.
And if we take a little bit closer look, so we can see it has a completely new UI, and one of the nice features about the new Memory Browser is that as you select things in the center, so you're selecting the hex, will track the selection on the right and the left.
So we'll show you which addresses correspond to that, we'll show you what the ASCII version of that hex you have selected is as well.
Of course, you can type the memory address in and then page through memory so you can look at any pieces of memory that you want.
That's a really powerful way to look at your data.
And now, Hahn Ming is going to give us a quick demo of that.
Hahn Ming Wong: Hi.
I'm back. Welcome back to the third half of the demo.
So this part here, I'm supposed to show you the Variables View.
So I'm going to start, and I have re-enabled the breakpoint that is in the image processor file that I talked about earlier, the one that was in the default priority queue.
So I'm paused right now, and you can see in the Variables View, like Ken said, I'm showing you a list of variables.
It started in alphabetical order, but it's still a long list, you know, and which is why the filter comes in handy.
What I want to know is the thumb size nail to make sure I'm scaling down to the right size.
So I can nail the size there you, go size 48, yeah.
That's what I want.
That's still eight characters too many for me because I'm derived user typing on a freaking standard keyboard.
What I really want is the auto-view.
So I switched to that, what it's doing again, is using heuristics to find out all the relevant variables for this PC.
In this case, it's showing four.
Or sometimes, it's shows five.
I can deal with four or five, and it's right here 48.
And without typing in anything, it helps you streamline a workflow to find the relevant information, even though there's a lot of it.
And last thing before I hand you back to Ken is this is the on the right hand side on your right is the console area where you interact with the debugger.
I won't talk too much about it, except the fact that I'm using LLDB for my debugging needs.
If it didn't crash for me, it will not crash for you.
So go use it and file backs when you find it.
Thank you very much.
Ken Orr: OK.
So, so far what we've look at is we looked at the Core UIComponents that you're going to be using every day when you're debugging.
But what I'm want to do now is I want to show you kind of a few things, maybe on the periphery, that is you get more comfortable with Xcode 4, you'll discover these features and maybe try them out.
So the first one I want to show you is the Floating Debugger.
So the Floating Debugger is very useful if you're debugging graphics code.
So if you have overridden a draw method and you want to debug through that, what you don't want to happen is you don't want to click on Xcode and you don't want to become activated because that causes events to go your app.
And when you activate your app, it's going to cause more events, and drawing is going to happen and that's not what you want.
You want Xcode to stay on top, and you want it to not get these activation events.
And you can do that by selecting this Xcode Infront option.
And when you do when you select that, Xcode will shrink down to this little it's like a palette-type window, and it always stays on top, and it won't ever take it won't ever steal focus.
So it will stay in this light gray tool bar mode.
But it turns outs that sometimes, maybe you do want to give it focus.
So, you're debugging along, you're looking at your drawing code, and now, you want to look at the value of a particular variable.
Something's gone wrong, you want to print that out.
In Xcode 4, you can actually do that now.
So you can say, "OK.
I want Xcode 4 to get keyboard focus in this Floating Debugger mode."
And you indicate that by clicking on this little keyboard icon.
And when you click on that icon, you can also click on the Console button which will show you the console, and now, you can type in here.
While it's still on the small mini mode, you can print out your variable or do whatever it is you want to do from the console.
Of course, you can always leave the console up when you have Xcode in the don't-activate-me mode, and you can look at print outs or various other things.
But when you use these two things in conjunction, it gives you that power that you haven't had before.
So that's a Floating Debugger.
Another thing we have to show you is this new Schemes concept.
So what are Schemes?
Schemes are everything about building, testing and launching your application.
And it's all in this nice neat package, in this nice sheet that will slide down when we option click on the Play button.
So here's what that sheet looks like.
And from that sheet, we can do things like we can select a new debugger.
So if you want to try out LLDB, you can do that right from here.
If we switch to the Arguments tab, this is where you if you want to pass an argument to your application, you can do that right from the sheet.
You can also set environment variables.
If we go all the way to the right, to the Logging tab, this is where we now expose some features that were hidden before behind environment variables.
So things like Guard Mallet, some of the more advanced logging features.
Now, you can just click on the check box and turn that functionality on.
So it's really easy to get at that functionality.
Before we wrap up, I want to show you a few things that will maybe make Xcode 4 a little more fun for you to use every day.
The first one is now you can set all the colors in the console.
So before, you've been able to set the text colors, hadn't been able to set the background color.
Now, you can set all that stuff.
We'll track the theme that you have selected.
So if you want to choose like a dark theme, we'll track those colors in the console for you.
So, yeah. This feature is especially useful if you're one of those people that likes the dark theme.
Another thing that we've added is you can actually get at the history of old runs.
So you want to see the output from a previous run, you can do that now by going to the Log Navigator.
It's that navigator with that little button there.
And you can see two runs ago, you can look at an exception that occurred, and you don't have to go try to recreate that exception.
You can just go back to that previous run and see it.
So that's a big time saver.
And finally, this is probably the most powerful feature I think in Xcode 4, and it's my most favorite feature, and this is what I alluded to earlier.
This is the Alert System in Xcode 4.
So you can actually control the way Xcode behaves a little bit.
So when system events occur, you can say, I want such and such to happen.
So when you hit a breakpoint for example, so that's that run pause.
By default, we're going to show you the debugger.
Well, you can have other things happen.
If you want to play a sound or show a bezel alert, or just run some generic AppleScript, you can do all that.
Now you can make Xcode work around you, make it work the way you work.
So that's why I think this is such a powerful feature, such a great feature.
OK. So that's Xcode 4.
That's the smooth new debugging experience.
I hope you've enjoyed that.
We, of course, encourage you to go download it.
If you haven't already, go download it, try it out.
We want you to submit bugs.
We want to see the bugs.
But we also want to see how the useability is for you, how the new workflow is.
So if you can submit bugs including that information as well.
And of course, you can download it right there.
And with that, I will turn it over to Greg Clayton, who's going to talk to about LLDB.
Well, Thank you.
[ Applause ]
Greg Clayton: All right.
Now that you guys have seen some of the great things that the engineers have been working on the Xcode UI, let's take a little look of what we've been working on under covers.
Talk about a little bit what I'm going to go over today.
LLDB? Why did we write a new debugger?
What are some of the details about the debugger and give a little overview of the architecture.
We'll give you a brief demo and then we'll wrap things up.
So to start off, we want to talk about why we wrote LLDB.
We wanted to concentrate on 5 key things.
First and foremost was speed.
We also want to make sure that we're efficient with the memory resources that we take up while we're running and then talk about how we can be more accurate when it comes to setting breakpoints, evaluating your expressions and just overall debugging experience.
And we designed things that they're extensible so in the future we can kind of keep up with a lot of things that you know, a lot of the different targets that we're moving on to.
We currently have desktop.
We've got iPhone, got iPad.
Who knows what we have in the future and we want to be ready for it.
And we also want to make sure that we can reuse our code.
We put a lot of work over the years into GDB.
GDB has been, you know served us very well but when one of the unfortunate consequences is we can't share that code.
It's in a command line utility and we can't use that for other developer tools.
So we'll talk about-expand on that a little bit and we'll go over a little bit about the architecture.
LLDB is a framework that can be used of course from Xcode 4.
You've seen the debugging screens a little bit, so far.
We also for the people who prefer not to do command line debugging or who prefer not to debug in the UI but prefer to be in the command line, we've got an LLDB Command Line Tool.
I'll talk about that in a little bit.
And we also have Scripting Interface.
These all have access to the entire API inside of LLDB.
And of course, under the hood, we've got the Core of LLDB which has got a lot of plug-ins and a lot of these things that you guys don't need to worry about but it kind of goes back to the modularity of the design.
Next, we'll talk about performance.
One of the big problems that we've got in debuggers is there's a lot of information.
You guys have simple files.
You have a lot of information that we need to index and archive and look up in a variety of different ways, looking up things by address, looking up things by file line or looking up things by name.
We want to make sure that we index that information appropriately and make sure that we can access everything and do it in a speedy fashion.
And the modularity of the design allows us to kind of use the multiple threads that you've got in your desktop core by spawning new threads to index the information a little quicker.
Efficiency is one of the big things that we want to make sure that we're not taking too much of the memory when we parse up this information.
We do that by parsing the information a little smarter.
We want to make sure that when we ingest parts of the debug information we don't parse it all up front.
We like to call it Don't Ask, Don't Parse.
If we don't need to know the information we won't go off and track it down.
And also we try and parse the information to finer granularity.
It means, if we can go down to access information about single functions we don't have to ingest large chunks of data.
That helps us keep our memory footprint down and keeps our performance up.
We also think that we can do a great job with Multithreaded Debugging.
Today's cores have got, or today's machines have got a lot of CPUs and as we go into the future, there's just going to be more and more threads to worry about.
So, we ought to be better at showing you exactly what your threads are up to and why they stopped.
And per-thread states help us show you exactly what every thread was up to.
In GDB, GDB like to have a notion that there's one reason that your program has stopped and oftentimes in reality, your program can hit a lot of breakpoints - another thread might throw an exception.
We want to make sure that we're able to convey that information to you.
Also, controlling threads individually is another thing that we concentrated on.
We want to make sure that we can of course suspend and resume threads as well as do complex control actions with your threads such as stepping in, stepping out and stepping over your source code.
If you run and hit a breakpoint at one location and in some section of code and then you run, you're stepping over the source line and eventually end up somewhere else.
Well, you're kind of interested in the first task that you were doing but you also stops somewhere else because you set a breakpoint there and you obviously wanted to stop and take a look around.
We want to make sure that the actions such as the stepping that you are doing are stackable.
So, you stop one place, you end up somewhere else.
You step around and when you resume, you can kind of get back to that initial step that you were doing.
This kind of helps multithreaded debugging workflow a little easier.
Compiler integration was an important thing that we wanted to concentrate on.
We'll talk a little bit about why.
First off, a lot of debuggers go out and invent their own functions and their own types and their own variables, and this is great.
That's their internal representation then they take that internal representation and make an expression parser based off of it.
Well, one big chunk of work that we didn't want to do in the debugger was write an expression parser.
We happen to think the compilers are a little better at the job than we can be.
So we decided to integrate with LLVM.
So how do we do that?
First off, we start up by, when we're parsing through debug information we translate everything into an internal format that matches exactly what Clang and the LLVM tool chain wants.
How does that help us?
Well, we can let Clang do the expression parsing for us.
We already have everything in the exact format that LLVM and Clang needs and they can definitely parse the information and give us better and more accurate language support for all the variety of languages that they currently support.
And also the errors that you're used to seeing up in the Xcode UI will be very familiar to you.
You'll get those same errors back when you write an expression that's got some issues with it.
The new compiler features have come out.
We automatically get to support them.
We update our sources.
We kind of we get you know, for example, we've come up with block support over the past couple of years and I'm sure there are many features that are in the compiler.
We don't need to be worried in the debugger group about re-implementing something that's already been done for us.
And one of the exciting things, too, is Just in Time Compilation.
When we parse up these expressions, they're in a format that are ready to be ingested and compiled up into little chunks of code that we can put down in your program.
We currently have a few uses for those right now in stepping and other things that aren't anything that users tend to see but something that's happening behind the scenes.
Stepping into Objective-C functions is one of the things that's hard for us.
Doesn't seem like much to the average user.
But we also want to be able to take advantage of jigging up some code.
Maybe taking a snippet of code, downloading it down to the target and being able to run that for say data formatters or injecting code into your application.
There's a whole variety of uses that we haven't touched on yet but we'd love to get to in the future.
We also want to make sure that everything in LLDB was scriptable.
This kind of goes back to reuse.
We've got a debugger UI plug-in.
We've got a command line and we can also access things through Python.
We made our APIs such that they're very easy to hand off to some of the script interpreters.
The Script Interpreter Tool such as SWIG that allows us to give you guys the full access to the LLDB API.
So from Python, you can start up the target, you can set some breakpoints, you can run, it can help you do things for unit testing and a lot of other, and also for accessing all of your debug session internals while you're running.
So Python access where it's available from.
Well, we've got a command line tool, LLDB which can be started up and you type the script command, it drops you into the Python Scripting Interpreter.
We also have we can also access it through Python.
If we point Python into the directory that contains our LLDB module, start up Python and tell it to import LLDB.
We can then program using the API in there.
We also have access to it through the debugger console which is again, just the LLDB command line that you saw in Hahn Ming's demo and you've got access to the script command there.
You also have the ability to attach scripts to breakpoints.
So, if we set a breakpoint in LLDB and then attach a script to it using the breakpoint command add, you can add Python scripting to a breakpoint.
And why would you want to do this?
Well, if you stop somewhere, if you wanted to look up at the stack frames above you and see if the function name was the same or match the name of the function that you think that was causing your issue, you now have programmatic access to be able to kind of navigate around your processes, your threads, your frames and any of the variables so that's scriptability.
Breakpoint Resolution, we want to make sure we concentrated on setting your breakpoints.
Make sure that we stored them more symbolically for breakpoints that were set by file line or by name or by regular expression.
What do we mean by symbolically?
We want to make sure that as we go along, one breakpoint might turn in to many breakpoints and if you set a breakpoint by a name or by a file line, that file line might be in a file that contains inline code.
And we never stop looking for locations to set your breakpoint.
So as shared libraries get loaded and unloaded, we'll continue to look for file inlines that match your original query.
Also, I want to make sure individual locations can be enabled and disabled.
If you set a breakpoint and say standard template library header file, you might hit a bunch of template instantiations for types that you don't care about.
Under the same breakpoint you can see all the locations that got set using the Breakpoint List command.
And under there, you can then enable and disable individual locations so that you can still see all the locations that were hit by the breakpoint but you don't need to stop at all of them.
You also can limit the scope of the breakpoint to certain shared libraries that's used with the breakpoint command and that allows us to only look into certain locations, you know.
If you know your breakpoint for main is in your application, you can tell us to only look in that application.
That helps to save you some memory and saves some time when we're parsing up the debug information.
We want to work on a consistent command syntax.
We started off with and we want to make sure that was easy to learn.
Start off with something that is noun-verb for example, breakpoint set.
In each breakpoint, each command could also have options.
In this case, we set can set a breakpoint by file in line, by name, or by regular expression.
The options really help us make sure that the commands that you enter are unambiguous.
In GDB, oftentimes the GB has got a break command.
You enter in a big long string and we hope that GDB interprets that string correctly.
Sometimes, it gets it wrong.
Most of the time it gets it right but by providing command syntax it allows you to specify exactly what your thoughts were.
We can make sure that we do the right thing for you.
We also have Autocompletion- type in part of a command and hit tab and the LLDB command line we can complete that for you.
It will help you discover your commands and also be a little quicker in and around the command line.
We've got some help.
The help command can be typed in.
You can get help on any of the various commands that are inside of LLDB.
The different options that go with the commands know which options they go with.
So, when you type help, not only do you get a little blurb about what the command can do, but you also get information about which commands which command options go together.
For example, you wouldn't want to try and set a breakpoint at file in line and also by a name.
So, when you see the syntax and the usage coming from the commands, we'll show you the common sets of commands in the options that go together so you can see how the commands were intended to be used.
We also have an apropos command that allows you to type in one or more keywords and the keywords will be looked up and we'll find the commands that match those in case you're lost in looking for the command, you can find those.
I want to make sure that we let the people who like the command line know that we didn't forget about you guys.
We've got a command line tool that's available in Xcode 4 user bin.
It can easily be set up to launch a file for yourself, set a breakpoint and run but instead of showing you some slides about this, why don't we turn things over to show Sean Callanan.
He's going to give you a brief demo of the LLDB Command Line Tool.
[ Applause ]
Sean Callanan: Thank you, Greg.
Hi. I'm very excited about LLDB and it's a great honor to be able to demo it for you today.
So, I'm going to show you sort of the command line side of LLDB.
So, you've already seen from Hahn Ming how to use the debugger from the UI but for those of you who, you know, who've been using GDB for a long time, you'll probably want to be able to use the command line as well.
So, it's as Greg told you, you can start LLDB simply by typing /Xcode4/usr/bin/lldb.
Now, if you've used GDB for a while, you're going to expect to have certain basic features to help you find your way around the command line and if you're new, you're going to want to figure out what you can do here.
So, as Greg told you, you can use the apropos command.
Now, notice that I didn't specify what program I wanted to debug on the command line.
That's because I can load it.
I can load the program in using an LLDB command, but how do I do it?
So, I'm going to use apropos to help me find out.
So, if I type apropos executable, it tells me all the commands that are related to loading executables into the debugger and also some other commands that you might also have been looking for.
But in this case, we care about the file command.
But before I use the file command, I want to give you a demo of a new feature that we have in LLDB which is the Alias.
The user-defined aliases can be set not only for commands but also for commands and whatever options you use for them commonly.
So, if I want to set an alias for apropos, let's say that I'm very forgetful.
Now, I can type question mark executable and I get the same result.
So, that's very handy if you want if you spend a lot of time on the command line and don't want to have to type too much.
So, in just as in GDB, you have access to the Help command which by the way shows you all your aliases as well and all the commands that you have access to regularly.
All right, well enough of showing you around the just around our help facilities.
Let's actually do something.
So I'm going to load a WWDC demo up into the LLDB, and I'll use the file command as I found earlier.
Now, in order to launch it, I could launch it straight with straight inside LLDB but this is a command line app that I'm going to be running.
So, I'd like to show you another feature of LLDB which is that I can use the LLDB command line while the program is running.
So, I'm going to attach I'm actually going to attach to the program externally.
So, you type the process, attach command, and then I want to attach by name.
I could also attach by PID by the way, and I provide the wait for command option which indicates to LLDB that it should wait for me to start the program.
So, now I'll start the program in this other terminal.
All right, now the program has printed some out but LLDB stopped it.
So, now we need to type Continue to let the program run.
So, first of all, what does this little program do?
It's a little thing I hacked together that where you type in a number and it computes the factorial of that number.
That is if I type 3, it prints 1 times 2 times 3.
If I type 4, it computes 1 times 2 times 3 times 4, not rocket science here but what's interesting is that I'm doing it one of two ways.
An iterative way which simply uses a while loop and a tabled way which uses a recursive function that looks in a table to see if it's already computed the result for a particular number.
Now, if I want to set a breakpoint on both implementations of the factorial function, I can use the breakpoint set command but I pass it a regular expression.
So, I typed breakpoint set func_regex and I type fact.
Now, LLDB will hunt through and find all the functions that match this regular expression.
In this case, it's found two.
So, if I want to see which where it actually set breakpoints, I can type breakpoint info.
And as you can see, it set one breakpoint on the iterative factorial function and one on the recursive tabled one.
That's all very well and good.
Let's actually see it hit those breakpoints.
So, I'll type in five.
Now, I've hit the iterative factorial function.
Now, notice that LLDB provides you with several lines of source code context whenever you step or hit a breakpoint.
This is so that you don't lose track of where you are.
Our ultimate goal with LLDB of course is to completely phase out any Xcode 4 UI nonsense, so.
[ Applause ]
So, in this case, if I wanted to see more lines of source, I can type I can tell it exactly where to start and how many lines to print and in this and you see the iterative factorial function.
In this case, I'm implementing it using a while loop, you know, nothing too exciting here.
But if I type Continue and now hit the recursive version, now I can show you that entire function and notice that this first checks if the input is 0.
If so, it returns the standard recursive base case which is 1.
The factorial of 0 is defined to be 1 by somebody.
Otherwise, if the table entry hasn't been filled in yet, it computes the necessary value making a recursive call.
And finally, if the finally, it returns what's in the table.
However, we can do more than just look at the source code.
We can actually inspect the data structure since this is after all a running program.
So, the first thing we can do is I can simply type variable list to see what variables are available.
So, the first variable you're interested in of course is the input variable.
That's what we typed.
Then you see we have the table we have our table.
Now, notice that the first 5 entries, 0 through 4 are already filled in.
That's because when we typed 3 and 4 in earlier, it computed all those factorial values as part of its recursion.
Notice, however, that number 5 hasn't been filled in yet.
Well, we could let the program do it but, I mean, we don't want a work our programs too hard.
So, let's help it out by using the Clang-based expression parser.
So, if I type xpr that triggers the expression parser.
Now, I can type fact sub N and notice that this table entry has, I told you, hasn't been filled in yet.
But if I type in fact sub N equals fact sub N minus 1 times N which is the recursive step then it fills in that entry in the array.
It's using Clang to compile this expression and then we can execute it very simply.
This is what Greg was talking about when he was talking about LLVM integration.
Now, let's make sure that I'm not hiding anything behind my back and actually step through this and see that this actually worked.
So, if I type next, first of all, it checks that N equals 0, N was 5 so that's not going to happen.
Now, it checks if the entry in the table is blank.
Well, actually, since we used the Clang-based expression parser to fill our table entry in, we're perfectly fine.
So now I can finish to step out and type Continue and as you can see, we've got the correct result but we used the Clang-based expression parser to get it.
So, now before I hand you back to Greg, I'd like to show you one more exciting feature about LLDB.
I've shown you our integration with Clang but now I also want to show you the integration with Python.
Python-based scripting is going to make your debugging experience a lot easier and you'll be and if you happen to have a lot of things that you do repeatedly, this is going to really help you out.
So, right from the LLDB command line, you have access to the script command.
The script command dumps you into this little command prompt that has 3 greater than signs.
If you're familiar with Python, this command prompt will be very familiar to you.
This is a standard Python interpreter.
So, in particular, I can pull in external functions.
Now, since the particular demo I'm going to show you is a little this involves a slightly long command.
I'm not going to type that all in but I'm going to import it for me.
Now, to show you that I'm not doing anything, pulling a fast one on you, I'm actually going to use the Python standard interface to print that script.
What this script is doing is using the LLDB public API to do things like get the target, get the process, then get the current thread, look at the top look at the topmost stack frame in that thread and get its name and then see how many frames on the stack, match that name.
So, you're getting the recursion depth and now I'm going to use this.
And I'm going to use it as a breakpoint action.
Now, this is where things get exciting.
I'm going to disable the breakpoint on the non-recursive function.
Remember when I showed you the breakpoint where there 2 parts to that breakpoint so I'm disabling one and now, I'm going to add a command.
[ Pause ]
And now if I type a 7 here, notice that I hit the breakpoint 3 times, one with a depth of 0, one with a depth of 1, and one with a depth of 2.
Greg Clayton: All right, so, in conclusion, developer preview with Xcode 4, we've got an LLDB command line debugger for you guys, Python integration, Open source now.
Anyone who's willing to help, please feel free to head over to lldb.llvm.org.
If you guys have any questions, see us down in the dev tools lab.
Thanks a lot.