Skip to content

Commit 1d1908d

Browse files
committed
host: make message formatting/escaping uniform.
1 parent d7fd204 commit 1d1908d

File tree

1 file changed

+16
-41
lines changed

1 file changed

+16
-41
lines changed

cmd/host/src/lib.rs

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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

173150
fn 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

Comments
 (0)