TweetFollow Us on Twitter

Code Mechanic

Volume Number: 13 (1997)
Issue Number: 5
Column Tag: develop

Code Mechanic: Better Than Ever Stress Testing

by Dave Evans

There are few things more frustrating than losing access to your debugging tools due to a freeze, because you can't fix what you can't diagnose. The best course is to stop freezes before they start, so I'd like to share a common cause of freezes I've found. I'll also discuss some of the stress-testing options that are available to help you catch freeze-causing problems you might have missed, including an improved debugging tool.

Veteran readers of develop may notice a new title for this column. The previous title, "Balance of Power," was apt for its time, indicating a focus on PowerPC issues. But now that all new MacOS computers are PowerPC-based, everybody's writing about PowerPC, and my efforts in this area are complete. This new title reflects a focus on the mechanics of code tuning, with tips for improving your application's performance and stability, which I hope you'll find just as useful.

Protect Your Vectors

Even if you use a PowerPC-based MacOS computer, the first 256 bytes of memory are dedicated to 680x0 exception vectors, which the 680x0 software emulator uses to emulate 680x0 exceptions and interrupts. On a 680x0-based computer, these values are read by the processor itself when handling an exception or servicing an interrupt.

Under System 7, these important vectors are not memory protected. Any program can read from or write to them, possibly resulting in a serious failure. While not all of the vectors are used, modifying some of them will cause an immediate freeze, leaving you without access to your debugging tools. You probably don't address these vectors intentionally, but it often occurs accidentally when a nil pointer or empty handle is de-referenced.

Unintentionally reading from these vectors will produce a random result. In most cases the vectors are addresses of special system routines; these vectors can have any value, and they vary significantly from one computer model to another. As an example of how easy it is to cause a problem in this area, take a look at the following C code, similar to that found in some applications:

front_window = FrontWindow();
if (front_window->windowKind < 0)
 MyDeskAccessoryRoutine(front_window);

The developers didn't realize that FrontWindow can return nil when no windows are open. In that case the application de-references the nil pointer and makes a logical decision based on the sign of the half word at $6C in low memory, which is the high half of the interrupt level 3 vector. On most Macintosh computers released before 1995, this vector pointed into ROM starting at address $40800000. Because of this, the applications would test the high half word value of $4080, and they wouldn't run the desk accessory routine. This was the right behavior, but for the wrong reason; disaster was averted by luck.

Beginning with all PCI-based PowerPC computers, ROM starts at location $FFC00000. During the development of these computers, we found that applications with code like the above would crash because they executed unexpected code after comparing the new half word value of $FFC0. We were able to work around their problem by changing the interrupt level 3 vector to point to a routine in RAM. This changed the high half word value to be a small positive number, and the applications behaved as expected. Still, the best case would have been if the problem could have been avoided in the first place. The following code is an example of what would have been a better, crash-free approach:

front_window = FrontWindow();
if (front_window && front_window->windowKind < 0)
 MyDeskAccessoryRoutine(front_window);

Checking for nil pointers or handles is one way you can avoid these crashes in the first place. Checking for empty handles is another necessary step, since unlocked relocatable blocks that are marked purgeable may disappear any time memory can move.

To detect problems with purgeable blocks, you'll need tools to stress test your application. Utilities that display heap zones, allowing you to compact and purge a heap on demand, are a good start. For serious testing, however, you'll need a stress tool that operates all the time. One good tool for this is MemHell, which will compact and purge your heap whenever a Memory Manager routine that might move or purge memory is called. This slows down execution of your tests, but it will flush out problems with purgeable blocks.

So, while accidentally reading from low memory can cause unexpected results, accidentally writing to low memory can be fatal, and this is one of the most common causes of freezes that I've noticed. You may think this could never happen in your code, because none of your blocks are purgeable and you always check errors after allocating pointers. Think again; there are plenty of other opportunities. Do you check for an error after every GetResource call? Getting an unexpected error - from a corrupted resource file, for example - is one way you can end up with a nil handle. Besides diligent review of your code, you need to do stress testing to flush out possible errors, or freezes are likely to result.

Are You Stressed Enough?

There are a number of tools to help add stress to your testing. I've already mentioned MemHell for finding problems with purgeable blocks. You'll similarly need a tool to find reads and writes to the exception vectors.

The simplest choice is the ubiquitous and venerable EvenBetterBusError, written by Greg Marriott. This tool safeguards the first four bytes of memory, which are very often accidentally written over or read from. To detect reads, it places in the first four bytes of memory a value which when de-referenced will cause a crash. If you use a nil pointer or empty handle, the illegal value is likely to be used as data or de-referenced, leading to a crash. To detect writes, it checks periodically to see if the value that it placed has been overwritten; if so, you'll be notified with a DebugStr message. EvenBetterBusError is included as a dcmd in MacsBug beginning with version 6.5.4.

I've extended EvenBetterBusError to be more aggressive. The new version, YetEvenBetterBusError, writes a value over the first 256 bytes of memory which will cause a crash into your debugger when de-referenced. It also checks periodically for writes to these locations, but more frequently than EvenBetterBusError does. Like EvenBetterBusError, upon noticing a write to these locations it will notify you with a DebugStr message. YetEvenBetterBusError can be found at www.mactech.com.

To implement YetEvenBetterBusError, I had to sacrifice some compatibility with existing applications. Any application code that assumes the exception vectors start at address 0 will no longer function correctly. Most applications don't use the exception vectors directly, but some copy protection schemes do modify the vectors.

The correct way to determine the location of the exception vectors is by using the 680x0 instruction MOVEC, which must always be executed in supervisor mode. The location of the first vector is stored in the 680x0 VBR (Vector Base Register). To read the address, you would write the following assembly code:

_EnterSupervisorMode ; old sr result in d0
movec   vbr,a0   ; get the vbr
move.w  d0,sr    ; restore the old sr

Always use the VBR to find these vectors. Although early versions of the MacOS always placed them at location 0, they're now often elsewhere. When virtual memory is turned on, for example, the vectors will actually reside in the system heap, and the VBR will point to them. To maintain compatibility, however, if virtual memory doesn't handle an exception it calls through to the original vector table at location 0. This is why even with virtual memory on, writing over the low-memory exception vectors can still cause a freeze.

YetEvenBetterBusError is able to overwrite and then monitor the first 256 bytes of memory by moving the exception vector table entirely. So, even when virtual memory is on, with YetEvenBetterBusError installed the original low-memory vectors are never called. This is why some existing applications may be incompatible with YetEvenBetterBusError.

A Cure for Test Anxiety

It's true that fully testing your code to reflect all possible configurations and user actions can be a near-impossible task. But the perceived stability of both your application and the computer depends on how well we all write and test our software. To do the best possible job, use the stress-testing tools mentioned in this column or in the article "Squashing Memory Leaks with TidyHeap" in this issue. Do the right thing: stress test, then relax!

Thanks to Pete Gontier, Chris Jalbert, Bo3b Johnson, Dave Lyons, Quinn "The Eskimo!", and Keith Stattenfield for reviewing this column.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Luminar 3.0.1 - Powerful, adaptive, conf...
Luminar is the new full-featured image editor that adapts to the way you edit photos. Over 300 essential tools to fix, edit, and enhance your photos with comfort. The future of photo editing is here... Read more
iMazing 2.8.5 - Complete iOS device mana...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
OnyX 3.5.7 - Maintenance and optimizatio...
OnyX is a multifunction utility that you can use to verify the startup disk and the structure of its system files, to run miscellaneous maintenance and cleaning tasks, to configure parameters in the... Read more
TeamViewer 14.1.9025 - Establish remote...
TeamViewer gives you remote control of any computer or Mac over the Internet within seconds or can be used for online meetings. Find out why more than 200 million users trust TeamViewer! Free for non... Read more
Deeper 2.4.0 - Enable hidden features in...
Deeper is a personalization utility for macOS which allows you to enable and disable the hidden functions of the Finder, Dock, QuickTime, Safari, iTunes, login window, Spotlight, and many of Apple's... Read more
A Better Finder Attributes 6.16 - Change...
A Better Finder Attributes 6 allows you to change JPEG & RAW shooting dates, JPEG EXIF meta-data tags, file creation & modification dates, file flags and deal with invisible files. Correct... Read more
Boom 3D 1.2.3 - 3D surround sound and ph...
Boom 3D is a revolutionary app with 3D Surround Sound and phenomenally rich and intense audio that is realistic and works on any headphones. Features 3D surround sound Built-in audio player... Read more
Dash 4.6.1 - Instant search and offline...
Dash is an API documentation browser and code snippet manager. Dash helps you store snippets of code, as well as instantly search and browse documentation for almost any API you might use (for a full... Read more
iClock 4.6.5 - Customizable menu bar clo...
iClock replaces the old Apple's default menu bar clock with more features, customization and increases your productivity. Features: Have your Apple or Google calendar instantly available from the... Read more
Fantastical 2 2.5.7 - Create calendar ev...
Fantastical is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event details... Read more

Latest Forum Discussions

See All

PGC London '19: Kaijack Card Attack...
What would happen if giant monsters were indestructible? Wait, let me rephrase that. What would happen if giant monsters were real and indestructible? The answer, according to Kaijack Card Attack, is that they'd play a gamw somewhere between... | Read more »
Pre-register now for epic fantasy RPG Fi...
Final Blade is an epic fantasy RPG that revolves around two warring nations and one extremely powerful sword. Having already found great success in Taiwan and South Korea, the developer is now bringing its acclaimed free-to-play iOS and Android... | Read more »
The top 3 best iPhone and iPad games com...
The end of the week has rolled around. It's been a pretty good seven days for mobile gaming - if you want proof you can click here and check out our five favorite games that came out this week - but now we're going to turn our attention to the... | Read more »
The best games for iPhone and iPad that...
Every week here at 148Apps we like to make sure that you're up to date with all the awesome games that have come out for iPhone and iPad over the past 7 days. We pick the cream of the crop to ensure that you don't have to play anything boring and... | Read more »
The top 3 best idle games for iPhone and...
Sometimes you want to play a game where you don't really have to do anything. Don't worry, we're not here to judge you, we're exactly the same. We love some action when we're in the right mood, but sometimes we want something a little more chill -... | Read more »
The top 5 best games with great stories...
Last week we took a look at the best games for iOS that you could waste hours and hours of your life playing, so now we thought we'd have a look at the top 5 games for iPhone and iPad that have great stories. These are the tales that have stuck... | Read more »
Langrisser Mobile preview - Seminal TRPG...
Langrisser Mobile is set to finally break the revolutionary TRPG franchise's 20 year silence when the it finally makes its way to touchscreens the world over at the end of the month. The original Langrisser game (known as Warsong in the west)... | Read more »
Everything you need to win at Dragalia L...
Want to up your Dragalia Lost game? You've come to the right place. Here at 148Apps, we've been digging deep into Nintendo's latest gacha game to find the best tips, tricks, and strategies to share with all of our future co-op team mates (read: you... | Read more »
How will World of Warcraft, Starcraft, a...
You might have heard that Blizzard is bringing Diablo to mobile with Diablo Ultimate. There's been plenty of controversy surrounding that decision, and it's meant that a really important piece of information has been glossed over a little. Namely... | Read more »
The top 3 best iPhone and iPad games com...
Our mission here at 148Apps is pretty simple - we want to make sure that you're playing the best iPhone and iPad games in the world. Which is why, every Friday, we like to give you an insight into the incredible games that are set to rock your... | Read more »

Price Scanner via MacPrices.net

T-Mobile offers customers 64GB Apple iPhone X...
Trade in an eligible phone at T-Mobile, plus sign up for their $30/month Unlimited plan, and they will include a 64GB iPhone Xr for just $10/month extra for up to 4 lines. That’s $40 per month,... Read more
Amazon offers blowout prices on 10.5″ Apple i...
Amazon has 10.5″ Apple iPad Pros on sale for $150 off MSRP this week, with prices starting at $499. These are the cheapest prices currently available for 10″ iPad Pros from any Apple reseller, and... Read more
Lowest Apple Mac mini price ever: Only $379 t...
B&H Photo has previous-generation 1.4GHz Mac minis available today for $379 including free shipping. That’s $120 off original MSRP for this model, and it’s the cheapest price we’ve ever seen for... Read more
Space Gray and Silver 2018 13″ 1.6GHz/256GB M...
B&H Photo has new Space Gray and Silver 2018 13″ 1.6GHz/256GB MacBook Airs on sale for $100 off MSRP, or $1299. Their prices are the lowest available for these new models from any Apple reseller... Read more
Amazon has 2018 9.7″ Apple iPads on sale toda...
Amazon is offering 9.7″ WiFi iPads with Apple Pencil Support for $30 off MSRP today, with prices starting at $299. These are the same iPads found in Apple’s retail and online stores: – 9.7″ 32GB WiFi... Read more
Amazon has 2018 9.7″ Apple iPads on sale toda...
Amazon is offering 9.7″ WiFi iPads with Apple Pencil Support for $30 off MSRP today, with prices starting at $299. These are the same iPads found in Apple’s retail and online stores: – 9.7″ 32GB WiFi... Read more
Get a clearance 10.5″ iPad Pro from Apple sta...
Apple has Certified Refurbished 2017 10.5″ iPad Pros available for $100-$170 off original MSRP, depending on the model. An Apple one-year warranty is included with each model, shipping is free, and... Read more
Get a clearance 10.5″ iPad Pro from Apple sta...
Apple has Certified Refurbished 2017 10.5″ iPad Pros available for $100-$170 off original MSRP, depending on the model. An Apple one-year warranty is included with each model, shipping is free, and... Read more
B&H has 2017 13″ MacBook Airs on sale sta...
B&H Photo has 2017 13″ 1.8GHz MacBook Airs available today for $100-$270 off MSRP, with models available starting at $899. Shipping is free: – 13″ 1.8GHz/128GB MacBook Air (MQD32LL/A): $899, $100... Read more
B&H has 2017 13″ MacBook Airs on sale sta...
B&H Photo has 2017 13″ 1.8GHz MacBook Airs available today for $100-$270 off MSRP, with models available starting at $899. Shipping is free: – 13″ 1.8GHz/128GB MacBook Air (MQD32LL/A): $899, $100... Read more

Jobs Board

Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States- Apple Blossom Mall 1850 Apple Blossom Dr Job ID:1044618 Date:Today Job Read more
Sephora Product Consultant - *Apple* Blosso...
Sephora Product Consultant - Apple Blossom Mall Location:Winchester, VA, United States- Apple Blossom Mall 1850 Apple Blossom Dr Job ID:1056553 Date:Today Job Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States- Apple Blossom Mall 1850 Apple Blossom Dr Job ID:1042611 Date:Today Job Description Read more
Omni-Channel Associate - *Apple* Blossom Ma...
Omni-Channel Associate - Apple Blossom Mall Location:Winchester, VA, United States- Apple Blossom Mall 1850 Apple Blossom Dr Job ID:1074107 Date:Today Job Read more
Home Commission Associate - *Apple* Blossom...
Home Commission Associate - Apple Blossom Mall Location:Winchester, VA, United States- Apple Blossom Mall 1850 Apple Blossom Dr Job ID:1079517 Date:October Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.