Why does the following code throw an exception? Note that the file is a /proc/pid/stat
file so it could be interfered by the kernel.
// Checked that file does exist
try {
std::ifstream file(path.c_str());
// Shouldn't even be necessary because it's the default but it doesn't
// make any difference.
file.exceptions(std::ifstream::goodbit);
// Read the stream into many fields
// !!!! The exception was thrown here.
file >> _ >> comm >> state >> ppid >> pgrp >> session >> tty_nr
/* >> ... omitted */;
file.close();
} catch (const std::ifstream::failure& e) {
std::cout << "Exception!!!! " << e.what();
}
The exception was "basic_filebuf::underflow error reading the file".
Shouldn't the stream not throw an exception when we haven't asked it to (by setting file.exceptions()
)?
More info:
- It runs on gcc version 4.1.2 20080704 (Red Hat 4.1.2-54)
- The full code that causes the problem (without the try/catch part): proc.hpp
Best Answer
Update 2
I've even tried to force an error by manually setting tiny or huge buffer sizes:
I've verified that the read size were indeed tiny (7) using
strace
Interestingly, none of this failed.
Updated
in response to the comments, I have devised a standalone program that does exactly what the OP describes, but I can't reproduce the problem:
It runs happily on my machine, printing stuff like
Even if/when I torture it with
It just shows (presumably the
sudo
/ps
from the subshell)I have tried to read the information twice from the input stream (to force read-past-the-end type situation), but no luck.
Old answer text:
You need to establish under what kind of conditions the exception occurs. The following demo code works as expected on my system:
Prints, e.g.:
Update
I thought, on many systems the default buffer size is probably max 8192 bytes; let's create some silly long lines instead! Replacing the
system
call byresults in lines with 7 columns, taking ~29kB per line. The output is without hesitation and amounts to 2.8MiB of output, measured with
See it live on coliru:
Note that on Coliru, we can't access
/dev/urandom
, which is why I read from the binary itself. "Random" enough for this purpose :)