home *** CD-ROM | disk | FTP | other *** search
- /*** backtrace.c ***/
- /* Generate a stack backtrace
- * (c) Paul Field 1995
- * Based closely on code by Tom Hughes
- */
-
- /*
- 23 Oct 1996 JS. Added check that embedded fn name is < 4096 characters
- (there are 24 bits reserved for the name, but anything bigger than this
- is unlikely to be a fn name...
- */
-
-
- #include <assert.h>
- #include <stdio.h>
-
- #include "Desk.BackTrace.h"
- #include "Desk.Debug.h"
- #include "Desk.Error.h"
-
- #include "Defs.h"
-
-
-
-
- void Desk_BackTrace_OutputToFFunctionWithPrefix( Desk_backtrace_printf_fn fn, void* reference, const char* prefix)
- {
- _kernel_unwindblock frame;
- char *language;
-
- fn( reference, "%sStack-dump:\n", prefix);
-
- Desk_BackTrace_SupportCurrentFrame( &frame);
-
- while ( _kernel_unwind( &frame, &language) > 0)
- {
-
- Desk_function_name_info *Desk_name_info;
- unsigned int *Desk_save_code_pointer;
- unsigned int *Desk_frame_create_instruction;
- unsigned int *fp;
- unsigned int Desk_test_words;
-
- fp = (unsigned int*) (frame.fp & PCMask);
-
- Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: fp=0x%p\n", fp);
-
- if (fp != NULL) {
-
- Desk_save_code_pointer = (unsigned*) (*fp & PCMask);
- Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: save_code_pointer=0x%p\n", Desk_save_code_pointer);
-
- if ( Desk_save_code_pointer) {
-
- char* fnname = NULL;
-
- Desk_frame_create_instruction = Desk_save_code_pointer - SaveCodePointerOffset;
-
- Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: frame_create_instruction=0x%p\n", Desk_frame_create_instruction);
-
- /* Search backwards from the frame creation instruction looking for a 'name info' word */
- Desk_name_info = (Desk_function_name_info*) (Desk_frame_create_instruction-1);
-
- Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: name_info=0x%p\n", Desk_name_info);
-
- for (
- Desk_test_words = NameInfoSearchWordLimit;
- Desk_name_info->Desk_ff_code != 0xff && Desk_test_words > 0;
- Desk_test_words--
- )
- {
- Desk_Debug5_Printf( Desk_error_PLACE "BackTrace: name_info=0x%p\n", Desk_name_info);
- Desk_name_info--;
- }
-
- /* If we found the name info word we can print the name, otherwise the function is anonymous */
-
- Desk_Debug5_Printf( Desk_error_PLACE "Desk_name_info->Desk_ff_code=0x%x\n", Desk_name_info->Desk_ff_code);
- if ( Desk_name_info->Desk_ff_code == 0xff && Desk_name_info->length<4096) {
- fnname = (char*) Desk_name_info - Desk_name_info->length;
- Desk_Debug5_Printf( Desk_error_PLACE "fn name = '%s'\n", fnname);
- }
-
- fn( reference, "%s 0x%p (%s) (language is %s)\n",
- prefix,
- Desk_save_code_pointer,
- (fnname) ? fnname : "<anonymous function>",
- (language) ? language : "<unknown language>"
- );
-
- Desk_Debug5_Printf( Desk_error_PLACE "\n");
- }
- }
- }
-
- fn( reference, "%s\n", prefix);
- }
-