September 96 - Macintosh Q & A
Q What books and articles would you recommend that provide strategies for debugging?
A Here's a list of resources that can help you with debugging on the Macintosh: • How to Write Macintosh Software by Scott Knaster and Keith Rollin
(Addison-Wesley, 1992). This book describes how to find all the bugs you
wrote when you used memory manipulation in C.
• Debugging Macintosh Software With MacsBug, by Konstantin Othmer and
Jim Straus (Addison-Wesley, 1991), and MacsBug Reference and Debugging
Guide by Apple Computer, Inc. (Addison-Wesley, 1990). These books don't
describe the latest version of MacsBug; check the MacsBug 6.5.2 release notes
for additional details.
• "Macintosh Debugging: A Weird Journey Into the Belly of the Beast" by
Bo3b Johnson and Fred Huxham, develop Issue 8, and "Macintosh Debugging:
The Belly of the Beast Revisited" by Fred Huxham and Greg Marriott, develop
Issue 13.
• "Debugging on PowerPC" by Dave Falkenburg and Brian Topping, develop
Issue 17.
• "Balance of Power: MacsBug for PowerPC" by Dave Evans and Jim
Murphy, develop Issue 22.
• "KON & BAL's Puzzle Page," in every issue of develop since Issue 9.
Q I have a customer who's encountering a problem using my product. Can you suggest a way to use MacsBug to diagnose problems at a customer site?
A Yes. Here, in a few easy steps, is a technique for using MacsBug to diagnose problems in the field:
• Install a clean copy of the latest MacsBug.
• Create a file using ResEdit (or Resorcerer, or whatever) containing an
'mxbm' resource (which contains MacsBug macro definitions) and install it
into the MacsBug Preferences folder.
• In this 'mxbm' resource, define the macro everytime to call the stdloginto
macro as follows:
stdloginto 'Send to the programmer'
• This way, if MacsBug is ever invoked due to a program error, a log of
what occurred will be automatically generated. The log, named "Send to the
programmer," will appear on the desktop.
• Have your customer send you the log file created by the above steps.
See page 219 of the MacsBug Reference and Debugging Guide by Apple Computer, Inc.
(Addison-Wesley, 1990) for details of the everytime macro. For details of what the
stdloginto macro does, look at the 'mxbm' resource named "log stuff" in MacsBug's
resource fork.
Q We're developing an application that uses Apple Guide. It's working well on 680x0 Macintosh computers but is presenting a problem on the Power Macintosh, because of
AppleGuideGlue. If we import this library as "weak," the program runs but crashes
when we call any Apple Guide routines. If we import "strong," the program simply
refuses to run. What can we do?
A Linking with the .xcoff file produces a reference to a shared library named AppleGuideGlue. Unfortunately, the Apple Guide extension provides a library named
AppleGuideGlueLib instead, so the reference isn't resolved and the application fails to
launch.
The AppleGuideGlue.xcoff file has been changed to AppleGuideGlueLib.xcoff on the latest
Mac OS SDK CD. You can use that one, or just rename the one you have before including
it in your project.
In MPW, you can rename the library in the link process. If you're using Symantec C or
C++ or CodeWarrior, however, the name of the file has to be correct for the matching
library to be found at run time. Note that CodeWarrior ignores the ".xcoff" suffix if
it's present in the filename, while Symantec must have the ".xcoff" suffix to properly
include the file in the project.
Q My QuickDraw GX printer driver has a 'ptyp' of "A4 portrait" as the default paper type (via the isDefaultPaperType flag). But when a user chooses my driver from the
Page Setup dialog, A4 is selected as the default paper type in the desktop printer,
though my driver has no 'ptyp' named A4. How can I set my own paper type (A4
portrait) as the default?
A The paper-matching code is working incorrectly. QuickDraw GX internally adds the standard paper types (such as A4 and US Letter) to the options for your driver. The
bug is that QuickDraw GX thinks it's finding a better fit for the current page
dimensions than the assigned A4 portrait paper type. It then defaults to the internal A4
paper type.
The only workaround at this time is to remove the paper type that you're incorrectly
defaulting to. If you're defaulting to a nonstandard paper type, such as Letterhead,
Stationery, or Three-hole Punch, the best workaround is to remove that type from the
Extensions folder. If you're defaulting to another paper type, the easiest thing you can
do is to open your driver with a resource editor and remove or edit the 'ptyp' resource
for the paper type that's incorrectly matching. (Open the resource and you'll see the
paper type name embedded in the data.)
Q I'm creating a QuickDraw GX page that contains a line of single-layer text shapes, with each word a different color. The page displays correctly when it's opened in
SimpleText but shows a bug when it's printed to a PostScript printer: each line prints
with one color instead of each word being a different color. Any ideas?
A This is a bug that occurs only with single-layer text shapes that have a nil style in their face layer. There's a workaround that should be used anytime you do a one-layer
text face, except for italics -- this workaround slows down italic drawing but speeds
up all other cases.
Create a "generic" style object (with GXNewStyle) to replace the nil style. Set the text
size to 1.0 (important) and the pen to 0 in the style. The other fields are irrelevant to
this fix. Set your text face's style to this "generic" style and the problem will
disappear.
Q I'm having a problem, apparent at very small font sizes (6 points and below), with the output quality of some fonts that emerge from a QuickDraw GX vector driver. My
application uses gxLayouts for text display and editing. If I create my output using
GXDrawShape to render the layout shapes, the small characters begin to look very
crude: character height varies by about 30% between some letters, and curved letter
forms degenerate to rough polygons. What can I do to improve the quality?
A Layouts (like all typographic shapes) have hints turned on by default. If the font you're using isn't hinted at small point sizes, using hints messes up the appearance of
the text rather than helping it. Try using the layout shape and setting the
gxNoMetricsGridText and gxNoContourGridText bits in the text attributes. The results
at small sizes should be better.
Q I'm writing an Open Transport client program, and I'm confused about how to perform an orderly release when I receive the T_ORDREL message. When I get the
T_ORDREL message I'm supposed to call OTRcvOrderlyDisconnect. The documentation
for OTRcvOrderlyDisconnect says that I can then continue to send data but that I can't
read data without getting an "out of state" error (kOTOutStateErr). Is this correct?
A Yes, it is. Your confusion is due more to the dynamics and subtleties of X/Open Transport Interface (XTI) programming than to Open Transport itself.
Let's examine an orderly disconnect situation. Assume that two nodes have an
established TCP connection. Endpoint A has finished sending data and indicates closure
by invoking an OTSndOrderlyDisconnect call (this translates into sending an
end-of-file signal -- FIN -- over the wire). Endpoint B receives a T_ORDREL
message. If, however, B hasn't finished receiving the data, B must continue until it
gets back kOTNoDataErr. At this point, B initiates an OTRcvOrderlyDisconnect (which
acknowledges A's FIN). This is known as a "half-close"; B can still send data to A
(which will still receive T_DATA events), but if A attempts to send to B, A will
receive an "out of state" error.
A, of course, should also continue accepting data until receiving kOTNoDataErr. A
should then call OTRcvOrderlyDisconnect, thereby completing the other side of the link
teardown. Both sides can then unbind.
If, however, either endpoint's network code is written such that T_ORDREL and
T_DATA events are handled at different priorities (for instance, the T_ORDREL is
handled at the notifier, but the T_DATA is deferred to SystemTask time), a race
condition can occur. Your program must ensure that all data has been read before
calling OTRcvOrderlyDisconnect.
There's also a subtlety of XTI programming that you should be aware of. It's possible
that OTSndOrderlyDisconnect or OTRcvOrderlyDisconnect will return with a TLOOK
error. This means that there's another event pending; your program must call OTLook
to gather that event.
According to the XTI specification, the OTSndOrderlyDisconnect and
OTRcvOrderlyDisconnect calls can fail because of a pending T_DISCONNECT event. XTI
is trying to tell you that the connection to that endpoint broke. This can happen easily
in our modern, wacky, asynchronous world of networks, and your program will have
to call OTRcvDisconnect to acknowledge that your endpoint dropped.
Q I've implemented a server endpoint that hands off the connection to a hand-off endpoint. After the server processes a connect request with the OTAccept call, the
asynchronous handler for the hand-off endpoint is passed a T_DATA event. When the
handler makes the OTRcv call, however, it returns error -3168
(kOTStateChangeErr). Can you explain this?
A This problem occurs only when there's a hand-off (secondary) endpoint involved. The way Open Transport is implemented, it's possible for an asynchronous hand-off
endpoint to receive a T_DATA event before the connect mechanism is completed. After
accepting a connection, an asynchronous listener endpoint can expect to receive a
T_ACCEPTCOMPLETE call. The "accepting" or hand-off endpoint can expect to receive
the T_PASSCON event.
It's possible for the hand-off endpoint to receive the T_DATA event before receiving
the T_PASSCON event, and this apparently is what's happening to you. When this
happens, set a flag to defer receiving the data until later. After the T_PASSCON event is
received, check the flag and issue the OTRcv call if the flag is set. (Note that after