Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2006-308
$eventId
ID of event: wwdc2006
$eventContentId
ID of session without event part: 308
$eventShortId
Shortened ID of event: wwdc06
$year
Year of session: 2006
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC06 • Session 308

Debugging with Xcode

Development Tools • 44:29

The Xcode debugger makes it possible to rapidly discover the source of bugs in your program and track data flow over time. You'll learn how to develop more efficiently by taking advantage of powerful debugging features in Xcode.

Speakers: Chris Friesen, Stan Shebs

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Workflow changes with streamlined debugging. We're going to talk about how you can interact with your application, debug it, without Xcode becoming active using the debugger HUD, which is short for Heads-Up Display. And then we'll do a little technology preview with something called Rewind. You can guess what that might be. And then we'll talk about what debugging with Dwarf means. Since we last met, we've made a number of improvements, which are now in Xcode 2.3 and 2.4. The first are C++ template breakpoints.

We also introduced a pending breakpoint indicator. We now color the breakpoint indicator orange in 2.3 and 2.4. When you've asked for a breakpoint to be set, but GDB hasn't located the symbols for that yet either, the symbols haven't been loaded, That's basically usually whenever it happens. When the symbols haven't been loaded, then the breakpoint hasn't been set yet. Or you don't have those symbols.

That's another way that that breakpoint wouldn't be set. We also have registers in the variable view. They're always there now, before they were just there when you were in your disassembly. And they also show up in the expressions window, if you'd like to show them in a separate window.

And we now remember which format you've chosen. So if you have a variable and you want to display it as binary and you choose binary, we now remember which function that was and which variable name it was. And we'll try and restore that the next time you're in the same location.

And we also published a data formatter example, much requested, and you can find this up on Developer Connection. It's a good way to figure out how to go about writing your own custom data formatter so that for your own custom types, a summary will display in the variable view.

Now let's talk about streamlined debugging. With streamlined debugging, The goal here is to make debugging much more immediate and accessible. And to do this, we've introduced build and go. What build and go does is we've now merged build and run. The other part of streamlining the debugging experience is with merging the run log and the standard I/O log and the console log functionality into one window.

Third way is with the debugger bar. The debugger bar and the data tips allow you to debug your application directly in the file editor. So you don't have to go to any dedicated windows like the debugger window in order to debug your application. Now the main message with Build and Go is that you're always debuggable.

No matter how you start up, you can always click pause or enable your breakpoints, and then you can end up in the debugger to go through your code, view your variables, that sort of thing. Again, there is no more run and debug. There's just go. And you can go with your breakpoints enabled, or you can go with your breakpoints disabled.

Now when your breakpoints are disabled or turned off and you go, Xcode basically just launches your program. It comes up immediately, so you launch it from Finder. Now you can go back and if you decide you want your breakpoints enabled so you can hit them, you go back into Xcode and you can click turn on breakpoints. or you can click pause and then we'll automatically attach the debugger and show you exactly where you are.

Now for the console, we've replaced the run log and the standard I/O log. So now you don't need to go to any special window in order to interact with your application. So if your application takes input on the standard in, you can simply go type in the console.

You're saying, well, how do I talk to the debugger? Well, you don't need to talk to the debugger until you actually pause the application. And so then we'll show the debugger prompt to give you an indication when your typing is going to the debugger. And you can also choose various colors and fonts to help differentiate those states. And that's all on the Xcode preferences under debugging.

Now the next item is the debugger bar. It's this little piece up here that we've added to the file editor after you click "Go." So during your normal editing sequence, this won't be there. But as soon as you click Go, this appears. On the left, we have a pop-up that lets you select between different threads in your program. And on the right is a stack pop-up, so you can go between your stack frames.

And in the middle, starting on the left, we have... You can turn your breakpoints on and off. And then we have the Continue and Pause button. Continue and Pause are now one item. They're one menu item, and they're also one button. So currently, we're now paused, and it's showing you the Continue icon. Click Continue. It'll switch to Pause. Next to that, we've got Step Over, Step Into, Step Out.

And then the last two are show debugger window. So let's say you want to go to the debugger window rather than debugging in the particular file you were editing. Click that, and you get the full debugger window experience. Next to that is the console button. So if you want to jump immediately to the console, you can click that button there. Now data tips. How many people have been wanting this for a really long time? A lot of people.

Here's your data tip. Now, as you hover over a variable, we'll show the data tip for that variable value. Then, as you hover over it, each of the turndowns will automatically turn that down for you, so you don't have to click on it. If you want to close it, you have to explicitly click on it. Next to that, our little up/down arrow, which we'll go over later in the demo, which brings down a contextual menu that will let you actually do things like print the object, and then the console will come forward automatically. Now let's do a demo.

We'll open our demo application here. And we'll go up and turn off our breakpoints. And we'll simply click Build and Go. Our application comes up. We can interact with it. It launched very quickly. Now we can go back and say, you know, I want to see what's happening. I remember I had some breakpoints on.

We can go back here, click. Our breakpoints are now enabled. So now when we go back to our application, we hit our breakpoint. Here we see we have our debugger bar with the threads pop up. Currently we only have one thread. And we can also navigate to other places in the stack easily.

This doesn't have to be in the embedded editor. This can be in any separate editor window you might have open. If you want to debug your code right in the file editor, this is how you do it. Then of course we've got the Continue button here, and we can step over.

Now let's look at the data tips. So as I hover over self, we get a data tip. And I can drill down into it just by hovering over the little turn down area. That automatically drills down in. And then we can start to see, notice on the far right, our data formatters that would normally show up in the debugger window in the summary column are now showing up in our data tip.

So we can drill all the way down to this NS point. And if we want to go up and close this, I have to click. and then it closes that data tip. That keeps your window from getting too cluttered up and lets you go back if you've drilled down too far. Now this little icon here, the up/down arrow, indicates that you can left click on that and get a little contextual menu. So here I can choose print description. And then our window pops up, and here's the description for our SKT rectangle object.

Now the other thing we get in Data Tips are some debugger controls. You'll notice that I'm hovering over the gutter here, and I get a little continue icon. Now if I were to click on that, that would basically do an automatic continue to here. So immediately continue to this line, I'll click it now. We see we jumped down to that line, so I didn't have to do step, step, step in order to get to this line. So it's a way to easily get through your code without lots of button clicks.

Now the next way you can navigate through your code is if I hover over this method call, we'll see that I get a step in icon on the left. And when I click that, I'll automatically go to the next line and step into that method. Like this. So no more having to step down and then do a step in. It just happens.

Now as I hover over the gutter of the beginning of the method call, we see that I get the step out icon. So if I've stepped into something and I want to step out quickly, all I have to do is go to the beginning of the method and click step out. And now I'm back where I began. Now if the stepping controls are getting in your way for some reason, you can go up and you can toggle them to the second mode of the data tips, which just does the value pop-ups.

Let's go look at the preferences which have changed. So now that we just have Go under debugging, We now have a pop-up on what to do on Go. So this is currently set to do nothing. So Xcode will just leave all your windows the way they were. You can also choose to show the console. So every time you click go, this means the console will pop up. And then you can do the same for if you like working in the debugger all the time, you can choose show debugger or show console in debugger.

Now, if I want to see the full debugger window, I can simply click on the Show Debugger window. And here I have it collapsed. We can open that up. You can step as you normally would. Now if I actually go and I close the editor here, Xcode is smart enough to know, "Hey, I need to show where you are in one of the other open editors so it'll find the first one." So if I do a step over, we see that our other editor is showing where the PC is and showing the current code. So you can use the debugger window as kind of like a big inspector, if you like, if you actually go and close the editor in the debugger window. Now let's go back to slides.

So now let's talk about the debugger HUD. This is going to let you interact with your application without Xcode becoming active. So you'll actually be able to debug, step through your code, look at variable values using all the elements that we've just introduced. So it's a floating window, obviously.

It floats way high above everything else. It even floats up above the dashboard widgets, which may or may not be useful, but it's kind of interesting. And Xcode does not become active. So you're interacting with your application. You can do things like debug app will become active, that sort of thing.

And of course it lets you do all your stepping because it's got the file editor right in the debugger window. And of course, you can view your variable values. So here's the HUD in the run mode. Nice small little widget. You can stop your application. You can pause.

You can click the Next button, which will take you to Xcode. And then the last button there on the right enables and disables your breakpoints. So you can have a set of breakpoints that you have enabled and disabled, and this will turn them on and off. So the actual state of your breakpoints doesn't change. You just aren't actually hitting any of them. So we've gone and it's as though you went and typed disable on the GDB console, if you're familiar with that.

And then as the HUD switches to the pause mode, it expands, shows you the file editor, shows you your code or disassembly depending on where you are. And then you have the familiar debugger bar and you can use your data tips. And now Andreas will give us a demo of the debugger HUD.

So I wasn't really planning on being here today, but if you saw my demo on Monday, then you saw that it didn't quite work the last part. So of course, I couldn't let that stand. And I just want to make sure that I give the demo once. So we're on the demo machine. Here's my little project. It's this Core Recipes project again. And this time I can run it. And if the demo gods are with me, I now have data in it too. So that works, yes.

So here's my full screen mode again. Now I can actually step away from my machine and go in the kitchen and prepare my recipe. But we wanted to debug this. So here's the little menu item to bring up the debugger heads-up display. And if I go back into my application and actually activate full screen mode again, you can see that the debugger just floats over my window, even over full screen mode, and it's right here accessible to me.

The other thing that's great about it is that it's so small, right? So it doesn't interfere much with the screen estate. So like Chris explained, I can now go and turn on my breakpoints, for example. And I've set two breakpoints here. The first one, when I drop out of full screen mode.

So let me press my button. And as you can see, the debugger has now expanded nicely here. It's still floating above my window. I can use stepping. I can still use data tips, all the nice little things. And the key is, like Chris said, we don't interfere with the events of the application.

So this debugger is now running without actually stealing or changing the event flow in the application you are debugging right now. So let me go ahead and continue. And the other breakpoint I said is, on the method, on a notification that is invoked when my application gets activated.

And that is, for example, one of the things you couldn't debug before without the HUD, because when you hit a breakpoint and application will activate, then you had to drop back into Xcode, and that deactivated the app you were debugging. Of course, that didn't work. So let me just drop into Finder here. And I'll click back into my application. And as you can see, the debugger HUD again comes up.

I can again step, I can use data tips, all the other little things, continue, and now I'm back into my application. So that's the demo. The nice thing is that it's very small, it doesn't interfere much with your application, it stays on top of even full screen mode, and it doesn't interfere with the event flow in your application. So this really allows you to debug things that you couldn't debug before. Thanks.

We can go back to slides. Thank you, Andreas. It worked great. And now we'll have a little technology preview with Dr. Stan Shebs. Come on, Stan. Hello everybody. Hey, did you give me that? Hey, Chris, Chris, Chris, Chris. My mental powers are not enough to work this from afar. Anyway... So this is a kind of an unusual thing. First of all, I'd like to make a correction here that should read Frank middle initial n. OK, say it out. Say it too quickly.

Okay, so rewinding is about a situation where, say, you're stepping along in your code and you overshoot. You're doing stepovers and you realize you really wanted to do a step into and you went too far. So the normal thing you would do these days is you start your program over from the beginning. Another thing that some people do is they drag the PC back. How many people actually do this? Ah, okay. Yes, there are a few perverts. Yes, you're violating just about every invariant you can think of by doing it, and sometimes it works.

So anyway, so we actually were thinking about this and say, well, what would be a better solution? And so what we have worked up is what has come to be called Rewind. I actually wanted to call it Time Machine, but they told me it was taken. And then I wanted to call it X-Ray, and that was taken too. So we got left with Rewind.

So it basically consists of the ability to run the program backwards a limited amount. You turn it on with a checkbox in the general preferences. And then to actually do it, there's a button up in the top next to continue just called rewind. So now let's take a look at how that actually works.

This is a carefully selected demo machine. I sprinkled with oil from an IBM 704 power capacitor and sang a Bono song and hopefully it will actually run. Okay, so we have a good old sketch again. And we're going to draw a few rectangles. Select them all and then we'll align them. Now we just happen to have a breakpoint here, but we know the code's perfect, so... Now, left alignment isn't what it could be. Good enough for Vista, perhaps, but I think we'd like to do a little better.

But it is kind of mysterious, you know, so let's backpedal here in the application and then ask for... Alignment again, stop at our conveniently located breakpoint, just happens to be in the align left edges method. And we'll do single steps. Everything highlights as it should be. That's interesting. These two values should be the same.

We go down and look at a source code and it says, you know, there's a routine in there called funky. That's got to be a bad sign. So, we go to our handy rewind button. Boop. Gone backwards. PC went up rather than down. And that's good enough to get us into a step into, and voila, we're now inside Funky.

So we can now step along and observe. It is kind of interesting that there's a factorial function in left edge alignment. What's that all about? Now, Rewind will work in here. We can go back and go back out and see the variables get uninitialized. This is, we know it's a technology preview because it would be really stylish to do the undone variables in red, but that's not happening. We can continue forward and see, observe the code has done the same thing as it did before. So that's Rewind. Go back to the slides, please.

Okay, now let's talk about how this really works. Okay, it's not quite as magical as it appears. It's basically we record the program's registers and memories after you do steps and continues. And right now in the preview version, it's actually done by brute force. We actually call fork and save away the child process, kind of put it to sleep. And then when we want to get the old state back, when you click the rewind button, we just take the old state, copy it back in.

So... Hey, I said it was brute force. It does mean you can look at everything. I mean, it is actually your entire old state of the program. So you can look at globals, you can look at locals, you can look at backtraces. Much more complete than dragging the PC back.

However, it doesn't roll back the rest of the system. It's just the internal state of your own program. Everything is tied to the registers and memory. In a lot of cases, that actually turned out to be good enough, and you can actually single step forward, continue, rewind a little bit more, as you saw in the demo, and most of the time it works.

Some caveats to know about this, it can only undo what you did. And so, for instance, if I continue forward by 10,000 lines, I can't step back by one line. I have to jump back and then continue forward, or step forward 10,000 lines, or run forward to a breakpoint or whatever. I am limited to undoing whatever I did.

The only thing that really works totally reliably is to rewind and re-step through computation. It's always reliable to rewind. It's the stepping forward again that's problematic. Things that won't happen, it'll do a system call a second time. If the system call is, say, get a random number, well, you probably get a different random number. It's okay.

If the running forward was, say, to open a file, the system actually thinks the file's already open. So probably running forward again a second time will say, hey, the file's already open, and the code will start going through a different path than it did the first time. So at that point, things can get a little strange. Surprisingly, printf, rerunning through printf usually does the right thing. But we've also seen internal error messages out of VM allocate.

Which is just not the level we want to hear from when we're debugging a printf program. Shared memory, we don't do anything special for shared memory yet. So if you have several applications writing into the same space and you rewind one of them, you'll end up copying back the old memory state into the shared block, and the other programs will have to make what they will of the shared memory being at some previous state.

date Anything external, state change, no, this really isn't time machine. It's not going to call files back from the dead. And it's not going to call back email messages that you wish you hadn't sent or anything like that. Now that said, we actually are experimenting with the ability to flip back a window state. You can do interesting things with the core graphics buffers in the windows. Hey, they're just blocks of memory, right? We copy blocks of memory. So, but I didn't dare show that.

And then finally, this whole thing is memory intensive. Now, the only, because we're doing fork and fork is copy on write, we're only actually making copies, you know, sort of incrementally making copies of blocks that are touched. So, you know, if you're, if you step, single step forward, it's really not using any more physical blocks of memory.

But if you're, say, you know, running Photoshop, you know, on big images, you're actually using a lot of memory. So, you know, if you're, if you're running a lot of images forward a long ways, you know, you will end up tying up a lot of blocks in VM.

So that's where Rewind is. We're about at the stage where the arm is twitching and the monster has yet to actually walk around. But we want everybody to give it a try. It's in your DVD. And let us know how it actually works for you, whether it's real useful or not useful, or if it erased all your files. So with that, we'll send you back to Chris and we'll talk about real stuff again.

Stan? Now let's talk about DWARF and what does this mean for you? We introduced DWARF in Xcode 2.3 and of course it's supported in 2.4 as well. What does it stand for? Well, as you can see, it stands for Debug with Arbitrary Record Format. I'm told that they came up with this after choosing the name.

So what is DWARF? It's an industry standard debug symbols format. It also uses variable size binary encoding, and it's a structure of interlinked and shared descriptors. Those all happen to be advantages. It's an advantage that it's an industry standard. Other people are using it. It also provides better debugger fidelity for C++.

For instance, support for namespaces and allows breakpoints and templates. And the debug executable files are also smaller on our platform when we use Dorf. How do we get more with less? Well, part of that's the variable size binary encoding. and also Dwarf will enable future capabilities with its expandable infrastructure.

In Xcode 3.0 and on Leopard, Dwarf is the actively supported symbol format. Stabs will be supported as is, and you should also be able to mix the two as well. It's the default for new targets that you create in Xcode 3.0. So if you open your project now that you've been working on in Xcode 3.0, we don't change it. Nothing changes. You still use stabs. Now if you create a new target, then we'll go ahead and you'll be using the Dwarf symbol format for any build products built by that target.

Now, if you're using GCC from the command line or make files for any open source projects you might be working on, -g will still generate stabs. You have to use -g dwarf -2 to generate dwarf symbols. Build configuration debug. The debug information format is obviously set to just plain DWARF.

The debug information is no longer linked directly into the executable or library. We keep the deepdwarf information stays in the object files. This speeds up linking because the linker doesn't have to copy all that information out of the .o files and put it in the executable or library.

And it also keeps the debug information out of the address space of your application. So if any of you had really large applications with lots of debugging symbols, those debugging symbols aren't loaded in when you actually go and run your application. Those are kept in the .o files. And GDB knows how to find those because there's a debug map in your executable that points back to them.

Of course, this means you can't delete your .o files or objects if you want to keep debugging that particular application with the debug build configuration. Now when you switch your build configuration to release, and you've created a new target in Xcode 3.0, you get DWARF with DSIM. DSIM file is a lot like the XSIM file in Code Warrior.

And typically you really only do this with the release build because generating that DSIM file takes a while, takes a lot of resources and time, and you don't want to be doing that when you're in your development cycle. So that's why when your build configuration is debug, we just choose dwarf and we leave all those symbols in the .o files.

So as I said, DSIM file, it's an archive that contains the fully linked DWARF information for your executable. This means you can go and you can throw away all your build products, all those .o files, and you just have to keep this one file archive around. So when you do a beta release or something like that and you want to strip your executable, you can do that, and then you just keep the DSIM file around. You'll be able to regenerate your backtraces.

Those DSIM files also contain a unique identifier inside the file that matches the UUID that's inside the executable. Now, the DSIM file is created by a utility called DSIMUtil that's run on your unstripped executable and with all those DATO files with your dwarf information still around. It goes through and it links all that information together, as I said before.

And as I said, you can strip your executable and ship it off to somebody, and they won't see your symbols. However, the DSIM file, whenever you're going back to use GDB on that executable, in order for GDB to find the DSIM file, it has to be located next to the executable that you're debugging.

So here's a pretty little graph that's going to show you what happens when you have the debug build configuration. It goes through, your source code's compiled, and your .o files with Dwarf. The link happens, you have your executable, it has a UUID in there, and the debug map, which is actually smaller than that, but the word's pretty large, points back to your .o files, which has all the Dwarf information.

Now when you switch to the release build configuration, a lot of this is going to look similar. But as you know, whenever you have a different build configuration in Xcode, all the build products are put into a different directory. So you can have your debug builds and your optimized release builds, and they'll be in two separate spaces, so you can switch back and forth between them without having to do a clean. So here we see we've gone through, we've built optimized Dorf information in the .o files, and the debug map points back to them.

The next thing that happens is DSIMUtil is run. It goes through, does a link of all the dwarf information in the .os and creates the DSIM file. And the UID matches the executable. And this is what happens automatically for you when you choose the release build configuration in Xcode 3.0.

Now the next step is currently manual in the seed you have, and that is to actually go through and strip the executable of the debug map. You won't have any debugging information that points back to your .o files. And this you should be able to safely give away to your customers and users, that sort of thing.

Now there are some tools for working with dwarf information. The first is DwarfDump. It dumps the various dwarf sections in all sorts of gory detail that most of you may not ever want to see. And you can also search through that dwarf information. For instance, you can pass it an address, and it'll go through and figure out which function that address is at.

And you can also do things like regular expression searches throughout all the Dorf symbols. So that can be a handy utility which you might want to check out. Then of course, DSIMUtil. That's the thing that we've talked about that goes through and creates the DSIM archive. It goes through and it also uniques the symbols as it's doing all this, which helps keep the size down.

There's also A to S. In the current seed, A to S does not currently work with your DSIM files, but we expect it to in the GM. That'll let you go through and symbolicate your backtrace. Basically, with A to S, pointed at an executable, and then you point it at your symbols, and you pass it an address, and it'll return back which function that address is at.

We talked about the future expandability of Dwarf. Well, we foresee having better C++ support. We also foresee having better debugging of optimized code. For instance, handling inline functions. will be able to tell, have the compiler generate symbols that will let us know when we're in an inline function, and then we can actually reflect that in the stack trace. So the stack trace will look like you've stepped into a function when that function is in fact inlined.

We'll also be able to track variable motion better. For instance, in your optimized code or just as you go further into your functions, variables can be moved in and out of registers. And we'll be able to track that better to give you more accurate information. And of course, more accurate backtraces, which everyone loves. And much, much more. Now let's do a demo of generating a dwarf DSIM file and stripping it and looking at the symbols. We can switch to the demo machine.

So here's Sketch again. I'm going to change the active build configuration to release, and I'll build that. And while that's building, we can go off and look at the target. I'll filter on debug, and we see that the debug information format is in fact Dwarf with DSIM file.

And I've also checked generate debug symbols, which is not something that you've usually done in previous versions of Xcode. Usually you just build your release with optimization and no debugging symbols. Now we encourage you to actually generate that information so you get the DSIM files. You also notice that strip debug symbols during copy is checked.

Now, if you just do a build from Xcode, we don't actually go ahead and do that last strip. You have to run Xcode build from the command line with the build action of install, and then that last strip will actually happen automatically. So it looks like our build succeeded. Go browse into our build directory. Here's release. Here's our sketch. So we'll drag that out. Now I'm going to go delete the build products. And just so you believe me, I'll empty the trash too.

We'll run Sketch. And now I'm going to crash Sketch because it doesn't like drawing circles. We'll generate the report, and we see that, hey, we still have a little bit of information here. This information in the backtrace-- so we still see some method calls into some of our custom code, SKT graphic view. And this information is actually information that's still in the debug map, because we haven't stripped our executable yet. But you'll notice that there isn't any line number information there. So how do we go about finding that? Well, we can use GDB here.

I'll tell it to run with the sketch on our desktop. Now we can do info line star, which is important, and pass it the address. And we see, hey, we couldn't-- it was looking for the object files. Well, that's because the DSIM file wasn't located next to the executable. Now let's go ahead and drag down. Copy this over here.

We'll run GDB again on our sketch now that our DSIM file is in place. And we'll run our command info line star past the address. And we see this maps to line 345 of our sources. So now let's look at an example, add an example, where we actually strip the executable. So I'm going to trash this. And now we're going to run strip minus X on Sketch.

Now when we run Sketch and cause it to crash, We get another crash report. And you'll notice that it now says that we crashed in start. What's this about? If we look over here, we actually had our symbol information. Well, what will happen when backtracers are being generated is that it'll keep looking until it finds a symbol name.

So since we stripped out everything, It'll go through as it's generating the backtrace, look through everything, it'll find the symbol start. So that's what it'll report. So if you're ever confused, some symbol looks like it's really where it shouldn't be, that's probably what's happening is you don't have any symbols and that's the first symbol that was found when the backtrace was being generated.

So now we can go and make sure our DSIM file is next to Sketch. We can run GDB on Sketch again. And we can do an info line, and there we see that it again bound the right line number. And now I'll show you what happens if you have your script executable and you try and do the same thing.

So if the executable is completely stripped, it'll say no line number information was found for that address. So there you see that. We've stripped our application. It doesn't even have the debug map in it. So there's very little the user can find out about your application without the symbols. Now let's go back to the slides. If we can go back to the slides, please. So now we have some hot tips for you. Now that GDB supports namespaces, you need to specify the namespace when you're setting a symbolic breakpoint in C++. So in this case, mine::testing.

[Transcript missing]

If somebody generates an executable on their machine and they have a different path to .o files or sources, you can actually use this command in GDB to map the parts of the path that don't match on their machine to where they're located on your machine. So that should make things much nicer. You don't have to specify lots of dir commands.

Since this is a mapping that maps part of a path to another path, you don't have to specify dir like you would for every single directory underneath, since the root is what you're replacing, and it'll find everything under that as long as everything else is in the same location.

Don't use dwarf with DSIM for development. It's slow. We've had some people that have chosen this when they were first exploring dwarf with Xcode 2.3, and you really just want to stick with leaving your dwarf information in the .o files when you're doing your development. Use dwarf with DSIM when you're doing a release, your nightly builds, that sort of thing.

Second hot tip is, since your release builds are now more debuggable, we're generating the dwarf information, if your PC error was hopping around, that's almost 99.9999% sure that you're debugging optimized code. Just keep that in mind. So today we've shown you new ways you can debug your application using the debugger HUD, debugging directly in the editor with the debugger bar.

We've shown you how to work with Dwarf files and Dwarf symbols. We hope that you'll all try this out immediately. Move on over to Dwarf. It's nice and comfy. And we've given you a small taste of future directions with technology like Rewind. For more information, you can contact Matt Formica. And of course, we've got documentation, sample code, and other resources on the WWDC website.