Setting breakpoints alters program behavior?
I've got a (C++, Carbon) command line tool that I'm debugging that uses libxml2 to generate XML.
Every now and then, it will print an error message "xmlEscapeEntities: char out of range" while it is processing input.
Since the input is fairly large, and I'm not sure exactly what input it is complaining about, I looked at the libxml sources, and discovered that there is a routine named "xmlGenericError" which is called to print out the error. So, when I was debugging the tool (in Xcode), I stopped at the beginning of the run, and set a breakpoint at xmlGenericError.
That certainly didn't work - now the tool crashes (about 1/2-way through the input) with an EXC_BAD_ACCESS error, deep in the bowels of libxml.
This is 100% reproducible - w/o the breakpoint the program runs, with one or two messages appearing on the console. With the breakpoint set, the program crashes.
What gives?
P.S. I once worked with a debugger that wouldn't let you set breakpoints in shared libraries until after "they had been loaded", so I set a second breakpoint in the program (after several calls to libxml had been made), and set the breakpoint on xmlGenericError at that point. No change.
Update (11/01) It turns out that "xmlGenericError" is a variable, not a function - it's a pointer to an error handling function.
Setting the breakpoint on the function made Xcode/GDB _much_ happier. I can't help but think that it could have _told me_ that I was trying to set a breakpoint on a variable, and maybe that wasn't what I meant.
Oh, well, this is Unix.
Locating bugs in my code
I was moving a chunk of code from CodeWarrior to Xcode, and Xcode decided that it didn't like some of the C++ that I had written. CodeWarrior had been happy with the code for a while. I looked at the code, and asked some friends, and puzzled over the (confusing) gcc error messages, and ?
Xcode was right.
My code (and CodeWarrior) were incorrect.
[ The problem was that I was passing a temporary object as a non-const reference; something that the standard does not allow. ]
Xcode can't remember?
In CodeWarrior, BBEdit (and MPW before that), when you open a text file, and then close it, the editor remembers a bunch of stuff about the file. Things like:
1) The position of the window.
2) The position of the text in the window (how far down/over you have scrolled the window.
3) The selected text
This is really cool, because when you re-open a source file, you are "right back" where you were when you closed it. You can arrange frequently opened files on the screen, and know that they'll be in the same place when you come back to work tomorrow, and the same piece of code that you were working on is still visible.
Apparently, Xcode doesn't do this :-(
Bummer.
Off to learn how to use BBEdit as an external editor, I guess.
Succeeded with one error
I was building a project of mine in Xcode yesterday, and I got an interesting message in the build results window.
My build, it seems, had "Succeeded with one error"
This, it seems to me, is "a definition of succeeded that I was previously unaware of" (with apologies to Douglas Adams).
I've got a screen capture of the bottom of the xcode:
Customizing Xcode's documentation window
Xcode's online documentation is quite handy. However, if you have a powerbook, it's also somewhat of a pain, because the documentation window is large, and multi-paned, and full of large text and images. It reminds me of old parodies of Microsoft Word, where there would be so many toolbars and sidebars that there was no room for the actual text.
I don't know of any way to fix that problem, but you _can_ make the text smaller, adjust the fonts used, etc in the Xcode documentation window.
Since most of the docs are lifted (repurposed) from Apple's web site, they're all HTML files, and they all share common (CSS) style sheets. You can edit the style sheets (they're just text files) and change the appearance of the window.
The main one to edit is "/Developer/ADC Reference Library/documentation/Resources/CSS/frameset_styles.css", but there are many css files in the /Developer hierarchy. You can look for styles that contain stuff like "font-size: 24px", and change them.
Explore! Have fun!
Application sizes: CW vs Xcode
So, this weekend I built my small application with both Xcode and CodeWarrior, looking to quantify the differences in the executable sizes. I found that after deployment, the Xcode executable was 808KB, while the CodeWarrior one was only 364KB (60% smaller). So I went looking in the files too see where the differences were. If the differences are inn the code generation, and Xcode applications are in general 120% bigger than CodeWarrior ones, then that's a serious problem. On the other hand, if the differences are all overhead, and don't change as the applications get bigger, then that's much less of a problem (although still a PITA)
Ok. Here's what I've found out so far:
The __TEXT segment of the Xcode executable is much larger than the CW one (557K vs. 212K). Most of this extra stuff is in two sections that don't exist in the CW executable "__textcoal_nt" (256K) and "__eh_frame" (136K).
Also, the __LINKEDIT section of the Xcode executable is much larger than the CW one (243K vs 124K).
Together, these three chunks alone make the Xcode executable half a megabyte (512K) bigger than the CW one. Without those, the sizes are quite comparable (the Xcode one would even be smaller).
Now, to figure out what those sections are for!
It's what you don't know that can hurt you
One of the "one step forward, two steps back" part of converting to Xcode is discovering where the assumptions are different.
I understand how CodeWarrior works; I've been using it for 10+ years. Xcode may look (superficially) similar, but deep down, it is radically different.
Here's an example: A default CodeWarrior project contains two targets, named " Debug" and " Final". You debug using the debug target, and then build the final target and ship what comes out. A default Xcode project also contains two targets, called "Debug" and "Release". You debug using the debug target, and then build the release target. But YOU DON'T SHIP THE RESULTS OF BUILDING THE RELEASE TARGET!
See what I mean?
If you're a CodeWarrior user, you're probably thinking "What is he smoking? Of course you do!". But with Xcode, that's not the case. You "deploy" it first. One of the steps in deploying involves running "/usr/bin/strip" on the executable, which removes debugging information that the linker put there. This is a good thing, because this makes your executables _much_ smaller.
[ Thanks to Chris E. for setting me straight on this. ]
Next up - side by side comparison of binaries.
Executable sizes
I have a simple application built with Nitrogen. It's called "DragPeeker X", which replaces the venerable Apple application DragPeeker, which was distributed with the "Drag and Drop Toolkit" in 1994, when the Drag Manager was new.
I got it building and running using Xcode, and it seems to work just fine.
However, I did a "Get Info" on the new app, and I was shocked - the application was about 3.2 MB in size! I went back and looked at the CodeWarrior executable, and it was about 600KB - much more reasonable. (But still too big for what it does)
I'm using gcc4, so that I am linking against the libstdc++.dylib, so the app should be smaller than before, right? (Since I don't have to carry around a copy of the C++ standard library).
So, what's going on here?
A little digging around shows lots of differences, but the big difference is the "LINKEDIT" section of the Mach-O binary. The CW binary has a section size of about 400K, but the Xcode LINKEDIT section is 2.6 MB!
In both cases the LINKEDIT section dwarfs the code actually in the application, but I don't know why the Xcode one is so much bigger (maybe it _is_ because of libstdc++.dylib)
Apparently I can't spell
Chris Espinosa, a friend of mine (and Manager, Developer Tools Productivity at Apple) informs me that the correct spelling is "Xcode", not "XCode".
Sorry about that, Chris.
I will try to do better in the future.