@@ -134,59 +134,40 @@ fn read_qualified_state_buf(
134134 Ok ( Some ( HostStateBuf :: from_value ( & as_static_cell. cell . value ) ?) )
135135}
136136
137- fn print_escaped_ascii ( mut bytes : & [ u8 ] ) {
137+ fn format_escaped_ascii ( mut bytes : & [ u8 ] ) -> String {
138138 // Drop trailing NULs to avoid escaping them and cluttering up our output.
139139 while let Some ( ( & b'\0' , prefix) ) = bytes. split_last ( ) {
140140 bytes = prefix;
141141 }
142142
143- if bytes. is_empty ( ) {
144- println ! ( "Message contains no non-NUL bytes, not printing." ) ;
145- return ;
146- } else {
147- println ! ( "Message is {} bytes long:" , bytes. len( ) ) ;
148- }
149-
150- let mut buf = String :: new ( ) ;
151- for & b in bytes {
152- match b {
153- b'\\' => {
154- // Escape any backslashes in the original, so that any escapes
155- // _we_ emit are unambiguous.
156- buf. push_str ( "\\ \\ " ) ;
157- }
158- b'\n' | b'\r' | b'\t' | 0x20 ..=0x7E => {
159- // Pass through basic text characters that we expect we might
160- // see in a message.
161- buf. push ( b as char ) ;
162- }
163- _ => {
164- // Escape any other non-printable characters.
165- buf. push_str ( "\\ x" ) ;
166- buf. push_str ( & format ! ( "{b:02X}" ) ) ;
167- }
168- }
169- }
170- println ! ( "{buf}" ) ;
143+ bytes
144+ . iter ( )
145+ . flat_map ( |& b| core:: ascii:: escape_default ( b) )
146+ . map ( |b| char:: from ( b) )
147+ . collect ( )
171148}
172149
173150fn host_boot_fail ( hubris : & HubrisArchive , core : & mut dyn Core ) -> Result < ( ) > {
174151 // Try old name:
175152 let d = read_uqvar ( hubris, core, SEPARATE_HOST_BOOT_FAIL_NAME ) ?;
176153 if let Some ( d) = d {
177- print_escaped_ascii ( & d ) ;
154+ println ! ( "{}" , format_escaped_ascii ( & d ) ) ;
178155 return Ok ( ( ) ) ;
179156 }
180157 // Try new name
181158 let buf = read_qualified_state_buf ( hubris, core, HOST_STATE_BUF_NAME ) ?
182159 . ok_or_else ( || {
183160 anyhow ! (
184161 "Could not find host boot variables under any known name; \
185- is this a Gimlet image?"
162+ is this a Gimlet image?"
186163 )
187164 } ) ?;
188165
189- print_escaped_ascii ( & buf. last_boot_fail [ ..] ) ;
166+ if buf. last_boot_fail . iter ( ) . all ( |b| * b == 0 ) {
167+ println ! ( "No boot failure message appears to be recorded (all NUL)" ) ;
168+ } else {
169+ println ! ( "{}" , format_escaped_ascii( & buf. last_boot_fail[ ..] ) ) ;
170+ }
190171
191172 Ok ( ( ) )
192173}
@@ -241,7 +222,7 @@ fn host_last_panic(hubris: &HubrisArchive, core: &mut dyn Core) -> Result<()> {
241222 . ok_or_else ( || {
242223 anyhow ! (
243224 "Could not find host boot variables under any known name; \
244- is this a Gimlet image?"
225+ is this a Gimlet image?"
245226 )
246227 } ) ?;
247228
@@ -299,6 +280,7 @@ fn print_panic(d: Vec<u8>) -> Result<()> {
299280 let ipd_pc = p. ipd_pc ;
300281 let ipd_fp = p. ipd_fp ;
301282 let ipd_rp = p. ipd_rp ;
283+ let ipd_message = format_escaped_ascii ( & p. ipd_message ) ;
302284
303285 println ! ( "ipd_error: {ipd_error}" ) ;
304286 println ! ( "ipd_cpuid: {ipd_cpuid}" ) ;
@@ -307,14 +289,7 @@ fn print_panic(d: Vec<u8>) -> Result<()> {
307289 println ! ( "ipd_pc: {ipd_pc:#x}" ) ;
308290 println ! ( "ipd_fp: {ipd_fp:#x}" ) ;
309291 println ! ( "ipd_rp: {ipd_rp:#x}" ) ;
310-
311- match std:: str:: from_utf8 ( & p. ipd_message ) {
312- Ok ( s) => println ! ( "ipd_message: {}" , s. trim_matches( '\0' ) ) ,
313- Err ( e) => println ! (
314- "ipd_message: {:?}\n (could not decode: {e})" ,
315- p. ipd_message
316- ) ,
317- }
292+ println ! ( "ipd_message: {ipd_message}" ) ;
318293 println ! ( "ipd_stackid: {}" , p. ipd_stackidx) ;
319294 println ! ( "stack trace:" ) ;
320295 let syms: Vec < String > = p
0 commit comments