comparison src/print.c @ 1957:59e1bbea04fe

[xemacs-hg @ 2004-03-19 02:59:08 by james] Break infinite loop that made debug-allocation unusable.
author james
date Fri, 19 Mar 2004 02:59:10 +0000
parents 01c57eb70ae9
children cc5b615380f8
comparison
equal deleted inserted replaced
1956:2aa9359b1615 1957:59e1bbea04fe
117 FILE *termscript; /* Stdio stream being used for copy of all output. */ 117 FILE *termscript; /* Stdio stream being used for copy of all output. */
118 118
119 static void write_string_to_alternate_debugging_output (const Ibyte *str, 119 static void write_string_to_alternate_debugging_output (const Ibyte *str,
120 Bytecount len); 120 Bytecount len);
121 121
122 /* To avoid consing in debug_prin1, we package up variables we need to bind
123 into an opaque object. */
124 struct debug_bindings
125 {
126 int inhibit_non_essential_printing_operations;
127 int print_depth;
128 int print_readably;
129 int print_unbuffered;
130 int gc_currently_forbidden;
131 Lisp_Object Vprint_length;
132 Lisp_Object Vprint_level;
133 Lisp_Object Vinhibit_quit;
134 };
135
136 static Lisp_Object debug_prin1_bindings;
122 137
123 138
124 int stdout_needs_newline; 139 int stdout_needs_newline;
125 int stdout_clear_before_next_output; 140 int stdout_clear_before_next_output;
126 141
410 if (len < 65536) 425 if (len < 65536)
411 { 426 {
412 Ibyte *copied = alloca_array (Ibyte, len); 427 Ibyte *copied = alloca_array (Ibyte, len);
413 memcpy (copied, newnonreloc + offset, len); 428 memcpy (copied, newnonreloc + offset, len);
414 Lstream_write (XLSTREAM (function), copied, len); 429 Lstream_write (XLSTREAM (function), copied, len);
430 }
431 else if (gc_currently_forbidden)
432 {
433 /* Avoid calling begin_gc_forbidden, which conses. We can reach
434 this point from the cons debug code, which will get us into
435 an infinite loop if we cons again. */
436 Lstream_write (XLSTREAM (function), newnonreloc + offset, len);
415 } 437 }
416 else 438 else
417 { 439 {
418 int speccount = begin_gc_forbidden (); 440 int speccount = begin_gc_forbidden ();
419 Lstream_write (XLSTREAM (function), newnonreloc + offset, len); 441 Lstream_write (XLSTREAM (function), newnonreloc + offset, len);
1533 return; 1555 return;
1534 } 1556 }
1535 } 1557 }
1536 1558
1537 being_printed[print_depth] = obj; 1559 being_printed[print_depth] = obj;
1538 specdepth = internal_bind_int (&print_depth, print_depth + 1); 1560
1539 1561 /* Avoid calling internal_bind_int, which conses, when called from
1540 if (print_depth > PRINT_CIRCLE) 1562 debug_prin1. In that case, we have bound print_depth to 0 anyway. */
1541 signal_error (Qstack_overflow, "Apparently circular structure being printed", Qunbound); 1563 if (!inhibit_non_essential_printing_operations)
1564 {
1565 specdepth = internal_bind_int (&print_depth, print_depth + 1);
1566
1567 if (print_depth > PRINT_CIRCLE)
1568 signal_error (Qstack_overflow, "Apparently circular structure being printed", Qunbound);
1569 }
1542 1570
1543 switch (XTYPE (obj)) 1571 switch (XTYPE (obj))
1544 { 1572 {
1545 case Lisp_Type_Int_Even: 1573 case Lisp_Type_Int_Even:
1546 case Lisp_Type_Int_Odd: 1574 case Lisp_Type_Int_Odd:
1710 LISP_TO_VOID (obj), BADNESS_INTEGER_OBJECT); 1738 LISP_TO_VOID (obj), BADNESS_INTEGER_OBJECT);
1711 break; 1739 break;
1712 } 1740 }
1713 } 1741 }
1714 1742
1715 unbind_to (specdepth); 1743 if (!inhibit_non_essential_printing_operations)
1744 unbind_to (specdepth);
1716 UNGCPRO; 1745 UNGCPRO;
1717 } 1746 }
1718 1747
1719 void 1748 void
1720 print_float (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 1749 print_float (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1855 1884
1856 /* Useful on systems or in places where writing to stdout is unavailable or 1885 /* Useful on systems or in places where writing to stdout is unavailable or
1857 not working. */ 1886 not working. */
1858 1887
1859 static int alternate_do_pointer; 1888 static int alternate_do_pointer;
1860 static char alternate_do_string[5000]; 1889 static int alternate_do_size;
1890 static char *alternate_do_string;
1861 1891
1862 DEFUN ("alternate-debugging-output", Falternate_debugging_output, 1, 1, 0, /* 1892 DEFUN ("alternate-debugging-output", Falternate_debugging_output, 1, 1, 0, /*
1863 Append CHARACTER to the array `alternate_do_string'. 1893 Append CHARACTER to the array `alternate_do_string'.
1864 This can be used in place of `external-debugging-output' as a function 1894 This can be used in place of `external-debugging-output' as a function
1865 to be passed to `print'. Before calling `print', set `alternate_do_pointer' 1895 to be passed to `print'. Before calling `print', set `alternate_do_pointer'
1890 else 1920 else
1891 #endif /* 0 */ 1921 #endif /* 0 */
1892 { 1922 {
1893 extlen = len; 1923 extlen = len;
1894 extptr = (Extbyte *) str; 1924 extptr = (Extbyte *) str;
1925 }
1926
1927 /* If not yet initialized, just skip it. */
1928 if (alternate_do_string == NULL)
1929 return;
1930
1931 if (alternate_do_pointer + extlen >= alternate_do_size)
1932 {
1933 alternate_do_size =
1934 max(alternate_do_size * 2, alternate_do_pointer + extlen + 1);
1935 XREALLOC_ARRAY (alternate_do_string, char, alternate_do_size);
1895 } 1936 }
1896 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); 1937 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen);
1897 alternate_do_pointer += extlen; 1938 alternate_do_pointer += extlen;
1898 alternate_do_string[alternate_do_pointer] = 0; 1939 alternate_do_string[alternate_do_pointer] = 0;
1899 } 1940 }
2010 2051
2011 static int debug_print_length = 50; 2052 static int debug_print_length = 50;
2012 static int debug_print_level = 15; 2053 static int debug_print_level = 15;
2013 static int debug_print_readably = -1; 2054 static int debug_print_readably = -1;
2014 2055
2056 /* Restore values temporarily bound by debug_prin1. We use this approach to
2057 avoid consing in debug_prin1. That is verboten, since debug_prin1 can be
2058 called by cons debugging code. */
2059 static Lisp_Object
2060 debug_prin1_exit (Lisp_Object ignored UNUSED_ARG)
2061 {
2062 struct debug_bindings *bindings =
2063 (struct debug_bindings *) XOPAQUE (debug_prin1_bindings)->data;
2064 inhibit_non_essential_printing_operations =
2065 bindings->inhibit_non_essential_printing_operations;
2066 print_depth = bindings->print_depth;
2067 print_readably = bindings->print_readably;
2068 print_unbuffered = bindings->print_unbuffered;
2069 gc_currently_forbidden = bindings->gc_currently_forbidden;
2070 Vprint_length = bindings->Vprint_length;
2071 Vprint_level = bindings->Vprint_level;
2072 Vinhibit_quit = bindings->Vinhibit_quit;
2073 return Qnil;
2074 }
2075
2015 /* Print an object, `prin1'-style, to various possible debugging outputs. 2076 /* Print an object, `prin1'-style, to various possible debugging outputs.
2016 Make sure it's completely unbuffered so that, in the event of a crash 2077 Make sure it's completely unbuffered so that, in the event of a crash
2017 somewhere, we see as much as possible that happened before it. 2078 somewhere, we see as much as possible that happened before it.
2018
2019
2020 */ 2079 */
2021 static void 2080 static void
2022 debug_prin1 (Lisp_Object debug_print_obj, int flags) 2081 debug_prin1 (Lisp_Object debug_print_obj, int flags)
2023 { 2082 {
2024 /* This function can GC */ 2083 /* This function can GC */
2025 2084
2026 /* by doing this, we trick various things that are non-essential 2085 /* by doing this, we trick various things that are non-essential
2027 but might cause crashes into not getting executed. */ 2086 but might cause crashes into not getting executed. */
2028 int specdepth = 2087 int specdepth;
2029 internal_bind_int (&inhibit_non_essential_printing_operations, 1); 2088 struct debug_bindings *bindings =
2030 2089 (struct debug_bindings *) XOPAQUE (debug_prin1_bindings)->data;
2031 internal_bind_int (&print_depth, 0); 2090
2032 internal_bind_int (&print_readably, 2091 bindings->inhibit_non_essential_printing_operations =
2033 debug_print_readably != -1 ? debug_print_readably : 0); 2092 inhibit_non_essential_printing_operations;
2034 internal_bind_int (&print_unbuffered, print_unbuffered + 1); 2093 bindings->print_depth = print_depth;
2094 bindings->print_readably = print_readably;
2095 bindings->print_unbuffered = print_unbuffered;
2096 bindings->gc_currently_forbidden = gc_currently_forbidden;
2097 bindings->Vprint_length = Vprint_length;
2098 bindings->Vprint_level = Vprint_level;
2099 bindings->Vinhibit_quit = Vinhibit_quit;
2100 specdepth = record_unwind_protect (debug_prin1_exit, Qnil);
2101
2102 inhibit_non_essential_printing_operations = 1;
2103 print_depth = 0;
2104 print_readably = debug_print_readably != -1 ? debug_print_readably : 0;
2105 print_unbuffered++;
2035 if (debug_print_length > 0) 2106 if (debug_print_length > 0)
2036 internal_bind_lisp_object (&Vprint_length, make_int (debug_print_length)); 2107 Vprint_length = make_int (debug_print_length);
2037 if (debug_print_level > 0) 2108 if (debug_print_level > 0)
2038 internal_bind_lisp_object (&Vprint_level, make_int (debug_print_level)); 2109 Vprint_level = make_int (debug_print_level);
2039 /* #### Do we need this? It was in the old code. */ 2110 Vinhibit_quit = Qt;
2040 internal_bind_lisp_object (&Vinhibit_quit, Vinhibit_quit);
2041 2111
2042 if ((flags & EXT_PRINT_STDOUT) || (flags & EXT_PRINT_STDERR)) 2112 if ((flags & EXT_PRINT_STDOUT) || (flags & EXT_PRINT_STDERR))
2043 print_internal (debug_print_obj, Qexternal_debugging_output, 1); 2113 print_internal (debug_print_obj, Qexternal_debugging_output, 1);
2044 if (flags & EXT_PRINT_ALTERNATE) 2114 if (flags & EXT_PRINT_ALTERNATE)
2045 print_internal (debug_print_obj, Qalternate_debugging_output, 1); 2115 print_internal (debug_print_obj, Qalternate_debugging_output, 1);
2404 DEFVAR_LISP ("print-message-label", &Vprint_message_label /* 2474 DEFVAR_LISP ("print-message-label", &Vprint_message_label /*
2405 Label for minibuffer messages created with `print'. This should 2475 Label for minibuffer messages created with `print'. This should
2406 generally be bound with `let' rather than set. (See `display-message'.) 2476 generally be bound with `let' rather than set. (See `display-message'.)
2407 */ ); 2477 */ );
2408 Vprint_message_label = Qprint; 2478 Vprint_message_label = Qprint;
2409 } 2479
2480 debug_prin1_bindings =
2481 make_opaque (OPAQUE_UNINIT, sizeof (struct debug_bindings));
2482 staticpro (&debug_prin1_bindings);
2483
2484 alternate_do_size = 5000;
2485 alternate_do_string = xnew_array(char, 5000);
2486 }