11 * These routines do their printing without using stdio. Stdio can't
12 * be used because it calls malloc(). Internal routines of a malloc()
13 * debugger should not re-enter malloc(), so stdio is out.
17 * NUMBER_BUFFER_SIZE is the longest character string that could be needed
18 * to represent an unsigned integer, assuming we might print in base 2.
20 #define NUMBER_BUFFER_SIZE (sizeof(ef_number) * NBBY)
23 printNumber(ef_number number
, ef_number base
)
25 char buffer
[NUMBER_BUFFER_SIZE
];
26 char * s
= &buffer
[NUMBER_BUFFER_SIZE
];
33 EF_Abort("Internal error printing number.");
35 digit
= number
% base
;
40 *s
= 'a' + digit
- 10;
42 } while ( (number
/= base
) > 0 );
44 size
= &buffer
[NUMBER_BUFFER_SIZE
] - s
;
51 vprint(const char * pattern
, va_list args
)
53 static const char bad_pattern
[] =
54 "\nBad pattern specifier %%%c in EF_Print().\n";
55 const char * s
= pattern
;
58 while ( (c
= *s
++) != '\0' ) {
63 (void) write(2, &c
, 1);
67 * Print an address passed as a void pointer.
68 * The type of ef_number must be set so that
69 * it is large enough to contain all of the
70 * bits of a void pointer.
73 (ef_number
)va_arg(args
, void *)
81 string
= va_arg(args
, char *);
82 length
= strlen(string
);
84 (void) write(2, string
, length
);
89 int n
= va_arg(args
, int);
100 printNumber(va_arg(args
, u_int
), 0x10);
104 char c
= va_arg(args
, char);
106 (void) write(2, &c
, 1);
111 EF_Print(bad_pattern
, c
);
117 (void) write(2, &c
, 1);
122 EF_Abort(const char * pattern
, ...)
126 va_start(args
, pattern
);
128 EF_Print("\nElectricFence Aborting: ");
129 vprint(pattern
, args
);
135 * I use kill(getpid(), SIGILL) instead of abort() because some
136 * mis-guided implementations of abort() flush stdio, which can
137 * cause malloc() or free() to be called.
139 kill(getpid(), SIGILL
);
140 /* Just in case something handles SIGILL and returns, exit here. */
145 EF_Exit(const char * pattern
, ...)
149 va_start(args
, pattern
);
151 EF_Print("\nElectricFence Exiting: ");
152 vprint(pattern
, args
);
158 * I use _exit() because the regular exit() flushes stdio,
159 * which may cause malloc() or free() to be called.
165 EF_Print(const char * pattern
, ...)
169 va_start(args
, pattern
);
170 vprint(pattern
, args
);