Skip to content
This repository was archived by the owner on Dec 15, 2021. It is now read-only.

Commit 9651c96

Browse files
author
Alex Helfet
committed
Decoder provides more information about end of file errors.
1 parent ee5c679 commit 9651c96

File tree

3 files changed

+42
-21
lines changed

3 files changed

+42
-21
lines changed

src/bin/itmdump.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -114,27 +114,24 @@ fn run() -> Result<()> {
114114
// We don't know this header type; warn and continue.
115115
debug!("{}", e);
116116
},
117-
Err(Error(ErrorKind::Io(ref e), _))
118-
if e.kind() == io::ErrorKind::UnexpectedEof => {
117+
Err(Error(ErrorKind::EofBeforePacket, _)) => {
119118
if follow {
120-
// FIXME: We can lose data here. UnexpectedEof is
121-
// returned when read_exact() encounters EOF
122-
// before it fills its buffer, but in that case it
123-
// may have already read _some_ data, which we
124-
// discard.
125-
//
126-
// Instead we could buffer input until we can read
127-
// a full packet, turn parsing into a state
128-
// machine, or create a reader that sleeps on EOF.
129119
thread::sleep(Duration::from_millis(100));
130120
} else {
131121
// !follow and EOF. Exit.
132-
133-
// FIXME: We may have reached EOF part way into a
134-
// packet but don't report missing data.
135122
return Ok(())
136123
}
137124
},
125+
126+
// FIXME: If in follow mode, we may try to read a packet
127+
// but reach the end of the file in the middle. Currently
128+
// we'd just return an error and hence exit. When we
129+
// receive an error, we've already read and discarded some
130+
// data, so we can't just go around this loop again.
131+
//
132+
// We could make a file following wrapper around `read`
133+
// that blocks in a loop retrying the read and sleeping if
134+
// there's no data.
138135
Err(e) => return Err(e),
139136
}
140137
} // end of read loop
@@ -155,4 +152,3 @@ fn open_read<'a>(matches: &ArgMatches) -> Result<impl io::Read + 'a> {
155152
None => Box::new(io::stdin()) as Box<io::Read + 'static>,
156153
})
157154
}
158-

src/decoder.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use error::{Error, ErrorKind, Result};
44
use heapless::Vec as HVec;
55
use packet::{self, Packet, Instrumentation};
6-
use std::io::{Cursor, Read};
6+
use std::io::{self, Cursor, Read};
77

88
/// Parses ITM packets.
99
pub struct Decoder<R: Read> {
@@ -29,7 +29,12 @@ impl<R: Read> Decoder<R> {
2929
/// for input if no full packet is currently an available.
3030
pub fn read_packet(&mut self) -> Result<Packet> {
3131
let mut header = [0; 1];
32-
self.inner.read_exact(&mut header)?;
32+
match self.inner.read_exact(&mut header) {
33+
Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof =>
34+
return Err(Error::from(ErrorKind::EofBeforePacket)),
35+
Err(e) => return Err(Error::from(e)),
36+
Ok(_) => (),
37+
};
3338
let header = header[0];
3439
match header & 0b111 {
3540
0b001|0b010|0b011 => {
@@ -48,7 +53,12 @@ impl<R: Read> Decoder<R> {
4853
};
4954
ud.payload.resize_default(payload_size)
5055
.expect("payload_size <= payload.capacity");
51-
self.inner.read_exact(&mut *ud.payload)?;
56+
match self.inner.read_exact(&mut *ud.payload) {
57+
Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof =>
58+
return Err(Error::from(ErrorKind::EofDuringPacket)),
59+
Err(e) => return Err(Error::from(e)),
60+
Ok(_) => (),
61+
};
5262

5363
Ok(Packet {
5464
header: header,
@@ -73,7 +83,6 @@ mod tests {
7383
use super::from_slice;
7484
use error::{Error, ErrorKind, Result};
7585
use packet::{Kind, Packet};
76-
use std::io;
7786

7887
#[test]
7988
fn header() {
@@ -146,8 +155,16 @@ mod tests {
146155
fn eof_before_payload() {
147156
let p = try_decode_one(&[0x01 /* Missing payload bytes */ ]);
148157
match p {
149-
Err(Error(ErrorKind::Io(ref e), _))
150-
if e.kind() == io::ErrorKind::UnexpectedEof => (),
158+
Err(Error(ErrorKind::EofDuringPacket, _)) => (),
159+
_ => panic!(),
160+
}
161+
}
162+
163+
#[test]
164+
fn eof_before_packet() {
165+
let p = try_decode_one(&[/* Missing packet bytes */]);
166+
match p {
167+
Err(Error(ErrorKind::EofBeforePacket, _)) => (),
151168
_ => panic!(),
152169
}
153170
}

src/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,13 @@ error_chain! {
1212
description("unknown header byte"),
1313
display("unknown header byte: {:x}", b),
1414
}
15+
EofDuringPacket {
16+
description("end of file during packet"),
17+
display("end of file during packet"),
18+
}
19+
EofBeforePacket {
20+
description("end of file before packet"),
21+
display("end of file before packet"),
22+
}
1523
}
1624
}

0 commit comments

Comments
 (0)