home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / Developer Documentation / Recipes, Tech Notes & Articles / Tech Notes / Utilities Documentation / Crawl < prev    next >
Encoding:
Text File  |  1995-11-05  |  5.1 KB  |  67 lines  |  [TEXT/ttxt]

  1. OpenDoc™ Utilities Documentation
  2.  
  3. Crawl: Examining the Stack
  4. 10 October 1995
  5.  
  6. © 1993-1995  Apple Computer, Inc. All Rights Reserved.
  7. Apple, the Apple logo, and Macintosh are registered trademarks of Apple Computer, Inc.
  8. Mac and OpenDoc are trademarks of Apple Computer, Inc.
  9.  
  10.  
  11. What It Does
  12.  
  13. Crawl is a utility that takes a snapshot of the current stack crawl or call chain and copies it into a small object on the heap. (The size of the object is about four bytes per stack frame.) The object can then be queried to find out the names of the various functions on the stack. This utility is not dependent on OpenDoc; it could be used in any piece of MacOS code.
  14.  
  15. Obviously this should only be used in a debug build of a program — messing with the stack crawl is skanky behavior to rely on in a shipping app! But there are many useful purposes for this:
  16. • A function can find out the name of the function that called it. This is useful for warning messages; the implementation of WARN in ODDebug uses this feature to display the name of the caller in the DebugStr.
  17. • A function can dump out the entire stack crawl to the log. This happens in the debug build when an exception is thrown, which makes it easier to find out where the original exception came from.
  18. • An object can store a stack crawl of the moment of its creation. You can then look at the object later to find out where it came from.
  19. • Memory leak detection is implemented as an extension of the above technique: the entire heap is scanned to find multiple objects with the same stack crawl, indicating a possible memory leak.
  20.  
  21. Setting Up the Build System
  22.  
  23. To use the Crawl utility, add Crawl.cpp to your project or makefile. Crawl calls the function unmangle( ) to convert “mangled” C++ function names into human-readable form; this function is in the library ToolsLibs.o (68k) or PPCToolsLib.o (PPC) which you can find in your development system folder. Add this library too or you'll get link errors.
  24.  
  25. Stack crawls are nearly useless unless the names of functions are embedded in the code; otherwise you just get hex addresses. This means you have to compile your code with MacsBug symbols (68k) or traceback tables (PPC). Consult your development system's manual to find out how to do this. In most integrated environments such as THINK or CodeWarrior there is a preference setting to turn on MacsBug/traceback symbols. (CodeWarrior 6 doesn't have a checkbox for traceback tables; you'll need to add a “#pragma traceback” statement at the start of your code.) In an MPW-hosted compiler it's usually a command-line flag.
  26.  
  27. The API
  28.  
  29. The API is a single C++ class called StackCrawl. It acts as a simple collection of stack frames, which are pointers into code. The frames are numbered from 0 (the top of the stack) with increasing numbers moving down the stack.
  30. Here are the methods:
  31.  
  32. StackCrawl::New( long startAt =0, long endAt = 0 )
  33. Creates a new StackCrawl object. (For technical reasons you can't just say “new StackCrawl(...)”.)
  34. If the parameters are omitted, you get the entire stack. Otherwise you can specify which frames to start and end at, the stack frames are numbered with 0 being the top of the stack (the caller of New) and the numbers increasing down the stack. The endAt parameter may be negative, which means to skip that many frames at the base of the stack; or zero, which means to go all the way to the end.
  35. Stack frames are deleted using the regular C++ “delete” operator.
  36.  
  37. CountFrames( )
  38. Returns the number of stack frames.
  39.  
  40. IsFrameNative( long frame )
  41. Returns true if the given stack frame is PowerPC code, false if it is 68K code.
  42.  
  43. GetFramePC( long frame )
  44. Returns a pointer to a stack frame. This points to the return address where execution will resume when the next function on the stack returns.
  45.  
  46. LookupSymbol( long i, char fnName[], size_t *offset )
  47. Returns the name of a frame's function in the string buffer pointed to by fnName, and the offset in the function of the return address in the offset parameter. If the function has no human-readable name (the source code was not compiled with MacsBug symbols or traceback tables) the name will be a hex string of the return address, and the function will return false. Otherwise it will return true.
  48.  
  49. GetFrameName( long frame, char name[] )
  50. A slightly more all-in-one way to get the name of a stack frame. The name[] string will contain both the function name and the offset. The return value is the same as LookupSymbol.
  51.  
  52. AsString( char[], long maxLen, const char delimiter[] )
  53. Converts the entire stack crawl — all the frames — into a single string by calling GetFrameName on each one and using the supplied delimiter string to separate each frame. The resulting string will be truncated if it would be longer than maxLen characters.
  54.  
  55. Hash
  56. Returns a 32-bit hash key. For use when storing stack crawls in a hash table.
  57.  
  58. operator ==
  59. operator !=
  60. Compares two stack crawls for equality or inequality.
  61.  
  62. In addition to the StackFrame class, there is a simpler function:
  63.  
  64. The Simplified API
  65.  
  66. GetNameOfCaller( char str[] )
  67. Copies the name of the calling function into the string buffer passed in. It returns true if the function has a human-readable name, else false.