home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / d / desklib / !DeskSrc / FN / Libraries / BackTrace / c / ToF < prev   
Encoding:
Text File  |  1996-10-23  |  2.8 KB  |  98 lines

  1. /*** backtrace.c ***/
  2. /* Generate a stack backtrace
  3.  * (c) Paul Field 1995
  4.  * Based closely on code by Tom Hughes
  5.  */
  6.  
  7. /*
  8. 23 Oct 1996 JS. Added check that embedded fn name is < 4096 characters
  9. (there are 24 bits reserved for the name, but anything bigger than this
  10. is unlikely to be a fn name...
  11.  */
  12.  
  13.  
  14. #include <assert.h>
  15. #include <stdio.h>
  16.  
  17. #include "Desk.BackTrace.h"
  18. #include "Desk.Debug.h"
  19. #include "Desk.Error.h"
  20.  
  21. #include "Defs.h"
  22.  
  23.  
  24.  
  25.  
  26. void    Desk_BackTrace_OutputToFFunctionWithPrefix( Desk_backtrace_printf_fn fn, void* reference, const char* prefix)
  27.     {
  28.     _kernel_unwindblock frame;
  29.     char    *language;
  30.     
  31.     fn( reference, "%sStack-dump:\n", prefix);
  32.     
  33.     Desk_BackTrace_SupportCurrentFrame( &frame);
  34.     
  35.     while ( _kernel_unwind( &frame, &language) > 0)
  36.         {
  37.         
  38.         Desk_function_name_info    *Desk_name_info;
  39.         unsigned int        *Desk_save_code_pointer;
  40.         unsigned int        *Desk_frame_create_instruction;
  41.         unsigned int        *fp;
  42.         unsigned int        Desk_test_words;
  43.         
  44.         fp = (unsigned int*) (frame.fp & PCMask);
  45.         
  46.         Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: fp=0x%p\n", fp);
  47.         
  48.         if (fp != NULL)    {
  49.             
  50.             Desk_save_code_pointer = (unsigned*) (*fp & PCMask);
  51.             Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: save_code_pointer=0x%p\n", Desk_save_code_pointer);
  52.             
  53.             if ( Desk_save_code_pointer)    {
  54.                 
  55.                 char*    fnname = NULL;
  56.                 
  57.                 Desk_frame_create_instruction    = Desk_save_code_pointer - SaveCodePointerOffset;
  58.                 
  59.                 Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: frame_create_instruction=0x%p\n", Desk_frame_create_instruction);
  60.                 
  61.                 /* Search backwards from the frame creation instruction looking for a 'name info' word */
  62.                 Desk_name_info = (Desk_function_name_info*) (Desk_frame_create_instruction-1);
  63.                 
  64.                 Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: name_info=0x%p\n", Desk_name_info);
  65.                 
  66.                 for    (
  67.                     Desk_test_words = NameInfoSearchWordLimit; 
  68.                     Desk_name_info->Desk_ff_code != 0xff && Desk_test_words > 0; 
  69.                     Desk_test_words--
  70.                     )
  71.                     {
  72.                     Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: name_info=0x%p\n", Desk_name_info);
  73.                     Desk_name_info--;
  74.                     }
  75.                 
  76.                 /* If we found the name info word we can print the name, otherwise the function is anonymous */
  77.                 
  78.                 Desk_Debug5_Printf( Desk_error_PLACE "Desk_name_info->Desk_ff_code=0x%x\n", Desk_name_info->Desk_ff_code);
  79.                 if ( Desk_name_info->Desk_ff_code == 0xff && Desk_name_info->length<4096)    {
  80.                     fnname = (char*) Desk_name_info - Desk_name_info->length;
  81.                     Desk_Debug5_Printf( Desk_error_PLACE "fn name = '%s'\n", fnname);
  82.                     }
  83.                 
  84.                 fn( reference, "%s 0x%p (%s)    (language is %s)\n",
  85.                     prefix,
  86.                     Desk_save_code_pointer,
  87.                     (fnname) ? fnname : "<anonymous function>",
  88.                     (language) ? language : "<unknown language>"
  89.                     );
  90.                 
  91.                 Desk_Debug5_Printf( Desk_error_PLACE "\n");
  92.                 }
  93.             }
  94.         }
  95.     
  96.     fn( reference, "%s\n", prefix);
  97.     }
  98.