KON & BAL'S PUZZLE PAGE:
Printing, Patching, and Fonts

Dave Hersey and Cameron Esfahani

See if you can solve this programming puzzle, presented in the form of a dialog
between guest puzzlers Dave Hersey and Cameron Esfahani (cam). The dialog gives
clues to help you. Keep guessing until you're done; your score is the number to
the left of the clue that gave you the correct answer. Even if you never run
into the particular problems being solved here, you'll learn some valuable
debugging techniques that will help you solve your own programming conundrums.

Dave Hey cam, it's kinda quiet. Where are KON and BAL?

cam Since the local salad bar closed, I haven't seen KON. BAL disappeared
after he left the video game industry. Have you been getting enough sleep? You
look tired.

Dave I've been under a lot of pressure to track down this bug.

cam Maybe I can help. What's the problem?

Dave I have a Power Mac 6100/66 running System 7.5 with QuickDraw GX 1.1. When
I try to print from a word processor, I get the message "The application has
unexpectedly quit, because an error of type 11 occurred." What's an error of
type 11?

cam That's an unhandled exception from native code. What word processor are
you using?

Dave Um, a very large one in a very large office suite from a very large
company up north.

cam Have you updated to version 1.1.3 of QuickDraw GX?

Dave Yeah. The problem still happens.

cam Does it happen on any other machine?

Dave Yes. It crashes on any Power Mac but works fine on 680x0 machines.

cam Hmm. Is the word processor native on the Power Mac?

Dave Yes -- it's fat.

cam It sure is. But I have the same version of system software and the same
word processor, yet my machine doesn't crash.

Dave Well, I have a standard system installed, but I added a bunch of whizzy
fonts.

Dave No way, man. This is a standard bitmap-only font. It should work. Ike's
machine doesn't have Thingamajigs on it and his machine still crashes.

cam Does he have bitmap-only fonts installed?

Dave Yes.

cam At what point in the printing process do you crash?

Dave The crash occurs just as the application starts spooling the print
file.

cam Is this word processor QuickDraw GX-aware?

Dave Yes. It has support for the new QuickDraw GX print dialogs, and it calls
the QuickDraw GX translator to translate QuickDraw drawing commands into
QuickDraw GX shapes during printing.

cam Good for them. Have you tried to reproduce the crash with other QuickDraw
GX-aware applications?

Dave Yup. I tried to reproduce it with several QuickDraw GX-aware and
QuickDraw GX-savvy applications. No luck.

cam Try running the 680x0 version of this program on your Power Mac. It will
be slow and piggy, but try it anyway.

Dave The problem went away! So, the crash seems to have something to do with
the PowerPC code in this application.

cam Hmm. Let's install MacsBug and take a look at this from the debugger.

Dave I tried that before, but I couldn't see any symbols in the PowerPC code
where it crashes. I couldn't tell which routine the PC was in.

cam You should install the new version of MacsBug. Version 6.5.2 understands
native exceptions and can use embedded symbols.

Dave Nifty. . . . OK, I've done that. But I still crash.

cam Why do you crash? Type how.

Dave MacsBug claims that there was a "PowerPC access exception at 001DB030
ConstructNFNTDirectory+002B4."

cam What does ConstructNFNTDirectory do? Hey, wait, there's Alex Beaman. Alex,
can you help us out here?

Alex Sure. QuickDraw GX views all fonts as type 'sfnt'. It's really elegant:
ConstructNFNTDirectory will make an NFNT font appear to have an 'sfnt'
directory. It can build either just the directory header or the entire
directory, and this is controlled by a Boolean parameter passed into the
function. OK, gotta run!

Dave Thanks, Alex. When I disassemble ConstructNFNTDirectory with MacsBug, I
get this:

cam An access exception means we're trying to read or write to an invalid
address. That, of course, could be caused by many things, such as uninitialized
variables or trashed memory. Let's check the heaps with hc.

Dave Both the system heap and the application heap are fine.

cam OK, I restart the program and use brp in MacsBug to set a breakpoint at
ConstructNFNTDirectory. brp is just like br, except it works for PowerPC code.
After I start printing and the breakpoint is hit, I step through this function
to follow the code flow.

Dave At offset 0x0300 you don't take that branch, and you eventually begin
executing code that will corrupt the QuickDraw GX heap.

cam But that's wrong -- we should've taken that branch. The caller didn't ask
ConstructNFNTDirectory to create the entire directory, just its header; it
didn't allocate enough space for all of it. Check the heaps again.

Dave The heaps seem fine. QuickDraw GX allocates out of its own heap, which
MacsBug doesn't know about. Even if it did know about it, it wouldn't be able
to tell us if the heap was corrupt, as QuickDraw GX has its own memory
manager.

cam Darn, memory corruption bugs are the worst. You can trash memory and not
see the effects of it until you're miles away from that code. OK, why didn't it
take the branch at offset 0x0300?

Dave Well, CR2 is true, so the branch won't be taken.

cam How can you tell that CR2 is true?

Dave The PowerPC chip has eight condition register fields, CR0 through CR7,
stored in nibbles in a 32-bit condition register (Dave Evans talked about this
in his column in develop Issue 21). So the value of CR2 would be bits 8 through
11 of the condition register. The chip has its bits numbered from 0 through 31,
from left to right. We can tell that CR2 contains a true value because its
second logical bit isn't set. That bit corresponds to the equals operator, so
the fact that it's 0 means the operation that set this register was not
equal.

cam Who sets up CR2?

Dave The code at offset 0x00F0. As Alex mentioned, one of the parameters to
this function is a Boolean that controls whether the whole directory is created
or only the header. Because this parameter is a Boolean, the PowerPC processor
can just compare it against 0 and use the result as a flag for later branches.
Parameters passed in PowerPC code are put from left to right into registers R3
through R10; since this parameter is the third parameter to the function, it's
passed to the routine in register R5. (A much better description of this is in
Inside Macintosh: PowerPC System Software.)

cam I love this chip. I'll reexecute the program and get back to the start of
this function and examine CR2.

Dave It starts out false.

cam So someone's trashing it along the way. Well, we can't use some of our
normal tricks for detecting when memory gets trashed. One problem is that step
spy doesn't work yet for PowerPC. Another problem is that we would want to step
spy on CR2, which is a register, and step spy never worked on registers. We'll
have to do this the hard way: let's
step through this function, watching CR2 to see just when it gets changed.

Dave The subroutine GetNoLoadResource at offset 0x0068 changes CR2 from false
to true. GetNoLoadResource is a wrapper to GetResource.

cam I restart the program and trace over the GetResource call.

Dave Yep, that's the function that trashes CR2.

cam Is it legal for the compiler to rely on CR2 being preserved across
function calls?

Dave Yes. According to the PowerPC ABI (Application Binary Interface)
documentation -- section 3.6 in the first edition -- CR2 through CR5 are
nonvolatile and need to be saved across function calls.

cam Look at the code for GetResource. Since in System 7.5 GetResource is a
native trap with a routine descriptor, I can use the MacsBug dcmd drd to dump
that out. Here's what I get:

Dave There's only one routine associated with the trap and it's the native
implementation.

cam Where's that function? On the Power Mac, every ProcPtr is actually a data
structure that contains the routine's real address and TOC. This is called a
TVector (transition vector). This allows every fragment to have its own
globals, because the correct TOC gets loaded for each routine by the runtime
environment. So, to find the routine's address, you need to dereference the
ProcPtr.

cam So this program is patching GetResource. At least they have a native patch
-- a good habit these days because you don't know what traps will go native
from now on. If you're patching native PowerPC code with 680x0 code,
performance-sensitive code will run slower. For this reason, you should make
all of your patches fat. Let's disassemble the patch on GetResource.

Dave At 0x00E77B9C they do a compare and store the result in CR2. However, they
don't save and restore CR2 across this function, so it's trashed when we return
to ConstructNFNTDirectory.

cam OK, I restart the program and manually save and restore the value of CR2
across the GetResource calls. I do this by futzing with bit 2 in CR2.

Dave Everything prints fine.

cam It looks like a compiler bug. Either they shouldn't be using CR2 or they
should be preserving it. In any case, the GetResource patch is trashing CR2,
and that changes a Boolean which causes us to read in extra data. The caller
never allocated enough space for the extra data, so the QuickDraw GX heap gets
corrupted.

cam Well, this company has their own in-house development tools group. They
write their own compilers, linkers, and debuggers. We should contact them
anyway, so that they can create a patch that fixes this problem. [This patch,
"Office4.2x Update for Power Mac," is now available on most online services.]

Dave Why are they patching GetResource?

cam It looks like they were looking for resources of type 'MBDF' (menu bar
definition procedures). I can tell this from the instructions at addresses
0x00E77B94 through 0x00E77B9C. The PowerPC architecture has a limitation of 16
bits on the size of an immediate constant. So, if you wanted to compare a value
against a 32-bit constant, you would have to build the 32-bit value with two
instructions. This is what occurs at addresses 0x00E77B94 and 0x00E77B98, where
they insert 0x4D42 and 0x4446 together into a 32-bit value. If you look at the
ASCII of this constant, it's 'MBDF'. At address 0x00E77B9C, they compare this
constant to the resource type parameter passed to GetResource. Since that
parameter is the first parameter, it will be in register R3.

Dave Why didn't we crash when we had only one NFNT font installed?

cam This patch would cause ConstructNFNTDirectory to always overwrite the
buffer passed in. But that wouldn't always cause your machine to freak out. By
adding enough NFNT fonts, we trashed the QuickDraw GX heap significantly enough
to cause the crash.

Dave Wow, all this and it was an application patch that caused the problem!
It sure would have been cool if we could have used the patch dcmd.

cam Yeah. The patch dcmd does works on the Power Mac -- but we didn't know
that was the problem when we started.

Dave It's interesting that it was an application bug. That would explain why I
crash in a spreadsheet application by the same company. They share the same
patch.

CAMERON ESFAHANI (AppleLink DIRTY, Internet dirty@powertalk.apple.com) is the
shortest member of the Graphics team at Apple. To add a few more inches to his
height, he sometimes wears roller blades in meetings. If that doesn't help, he
has been known to don his large purple hat with sparkles.*

SCORING

80-100 You could have a promising career writing compilers for a company up
north.

Software Updates via MacUpdate

Hopper Disassembler 4.3.16- - Binary dis...

Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more

Default Folder X 5.2.2 - Enhances Open a...

Default Folder X attaches a toolbar to the right side of the Open and Save dialogs in any OS X-native application. The toolbar gives you fast access to various folders and commands. You just click on... Read more

EtreCheck 4.0.1 - For troubleshooting yo...

EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more

Carbon Copy Cloner 5.0.9 - Easy-to-use b...

Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more

QuickBooks 17.2.25.638 R26 - Financial m...

QuickBooks helps you manage your business easily and efficiently. Organize your finances all in one place, track money going in and out of your business, and spot areas where you can save.
Built for... Read more

Monosnap 3.4.10 - Versatile screenshot u...

Monosnap lets you capture screenshots, share files, and record video and .gifs!
Features
Capture
Capture full screen, just part of the screen, or a selected window
Make your crop area pixel... Read more

Vivaldi 1.14.1077.50 - An advanced brows...

Vivaldi is a browser for our friends.
In 1994, two programmers started working on a web browser. Our idea was to make a really fast browser, capable of running on limited hardware, keeping in mind... Read more

Viber 8.2.0 - Send messages and make fre...

Viber lets you send free messages and make free calls to other Viber users, on any device and network, in any country!
Viber syncs your contacts, messages and call history with your mobile device, so... Read more

QuickBooks 17.2.25.638 R26 - Financial m...

QuickBooks helps you manage your business easily and efficiently. Organize your finances all in one place, track money going in and out of your business, and spot areas where you can save.
Built for... Read more

Carbon Copy Cloner 5.0.9 - Easy-to-use b...

Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more

Latest Forum Discussions

Our top 5 characters from casual RPG Cre...

Creature Quest definitely lives up to its name with a host of collectible creatures based on fantasy tales and world mythologies. To celebrate Creature Quest’s first birthday, we’re going to lay out what we think are the five best characters in the... | Read more »

Around the Empire: What have you missed...

Did you know that Steel Media has a whole swathe of other sites dedicated to all aspects of mobile gaming? Sure you'll get the very best iPhone news, reviews, and opinions right here at 148Apps, but we don't want you missing out on a single piece... | Read more »

All the best games on sale for iPhone an...

Oh hi there, and welcome to our round-up of the best games that are currently on sale for iPhone and iPad. You thought I didn't see you there, did you, skulking behind the bushes? Trust me though, the bushes aren't where the best deals are. The... | Read more »

The Battle of Polytopia Guide - How to H...

A new update just released for The Battle of Polytopia (formerly Super Tribes), which introduces online multiplayer. For all the fans of Midjiwan’s lite take on Civilization, this is certainly welcome news, but playing online isn’t as easy and... | Read more »

Here are the very best mobile games to p...

It's Valentine's Day! Did you get loads of cards and chocolates and other tacky, simple expressions of human affection? Did you send out tat because you find it almost impossible to express emotion unless there's a section dedicated to it at your... | Read more »

A laid-back mix of RPG and TCG, Creature Quest is all about building your deck, evolving your creatures and winning in battle. It’s the creation of VC Mobile, set up by Might and Magic producer Jon Van Caneghem. There are elements of that classic... | Read more »

Check out this awesome hands-on with the...

Well, PlayerUnknown's Battlegrounds has come out on mobile. This isn't a clone, this isn't a riff on the battleroyale mechanics of the game, it's the official mobile port by Tencent. But there's a little bit of a hitch.
[Read more]
| Read more »

Hostage Negotiator (Entertainment)

Hostage Negotiator 1.1.0
Device: iOS Universal
Category: Entertainment
Price: $3.99, Version: 1.1.0 (iTunes)
Description:
Official app of the board game by AJ Porfirio and Van Ryder Games.
In Hostage Negotiator, you play the part of... | Read more »

Price Scanner via MacPrices.net

Saturday Sale: Amazon offers 13″ 1.8GHz/256GB...

Amazon has the 13″ 1.8GHz/256B Apple MacBook Air on sale today for $250 off MSRP including free shipping:
– 13″ 1.8GHz/256GB MacBook Air (MQD42LL/A): $949.99, $250 off MSRP
Their price is the lowest... Read more

Roundup of Apple Certified Refurbished 12″ Ma...

Apple has Certified Refurbished 2017 12″ Retina MacBooks available for $200-$240 off the cost of new models. Apple will include a standard one-year warranty with each MacBook, and shipping is free.... Read more

Apple offers Certified Refurbished 10″ and 12...

Apple is now offering Certified Refurbished 2017 10″ and 12″ iPad Pros for $100-$190 off MSRP, depending on the model. An Apple one-year warranty is included with each model, and shipping is free:
–... Read more

Apple Canada offers Certified Refurbished Mac...

Canadian shoppers can save up to $560 on the purchase of a 2017 current-generation MacBook Pro, MacBook, or MacBook Air with Certified Refurbished models at Apple Canada. Apple’s refurbished prices... Read more

Adorama has the 8-core iMac Pro on sale for $4799 including free shipping plus NY & NJ sales tax only. Their price is $200 off MSRP, and it’s the currently lowest price available for an iMac Pro.
Read more

Sale! Walmart lowers prices even more on 9″ i...

Walmart has lowered their sale price on 9.7″ Apple iPads to $80 off MSRP for a limited time. Sale prices are for online orders only, in-store prices may vary:
– 9″ 32GB iPad: $249.99 $80 off
– 9″... Read more

Roundup of 13″ MacBook Pro sales, models avai...

B&H Photo has 13″ MacBook Pros on sale for up to $200 off MSRP. Shipping is free, and B&H charges sales tax for NY & NJ residents only. Their prices are the lowest available for these... Read more

MacTech is a registered trademark of Xplain Corporation. Xplain, "The journal of Apple technology", Apple Expo, Explain It, MacDev, MacDev-1, THINK Reference, NetProfessional, Apple Expo, MacTech Central, MacTech Domains, MacNews, MacForge, and the MacTutorMan are trademarks or service marks of Xplain Corporation. Sprocket is a registered trademark of eSprocket Corporation. Other trademarks and copyrights appearing in this printing or software remain the property of their respective holders. Not responsible for typographical errors.

All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.