7

I read /proc/<pid>/status this way:

std::ifstream file(filename);
std::string line;
int numberOfLinesToRead = 4;
int linesRead = 0;

while (std::getline(file, line)) {
    // do stuff
    if (numberOfLinesToRead == ++linesRead) {
        break;
    }
}

I noticed that in rare cases std::getline hangs.

  1. Why it happens? I was under impression that proc filesystem should be in somewhat consistent state and there should not be cases when newline is missing. My assumption was that getline returns false when EOF/error occurs.
  2. What is the recommended, safe way to read /proc/<pid>/status ?
lstipakov
  • 3,138
  • 5
  • 31
  • 46
  • 1
    That is the "proper" way to ready any text file line by line. However if the process you're checking exits while you're reading the file, then the behavior might be different compared to reading other text files. And no [`std::getline`](http://en.cppreference.com/w/cpp/string/basic_string/getline) doesn't return a bool value, it returns the stream [which can be used in a boolean expression](http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool). – Some programmer dude Aug 11 '16 at 08:16
  • As for your second question, there is really no safe way to read any file from `/proc//` because the other process might exit at any time. You probably need to use some other Linux-specific system call to get the status of the process, preferably in a direct system call with the kernel writing into a structure, rather than reading from a file using the standard C++ library. – Some programmer dude Aug 11 '16 at 08:19
  • 2
    I am surprised this should hang. I would suspect that' would be a bug maybe in the compiler, maybe in the `OS` because if another process removes a file from under you then that should cleanly generate an error in your file descriptor. And `/proc` is supposed to behave like any other file. Are you sure that that *exact* code causes his error? – Galik Aug 11 '16 at 08:36
  • @Galik yes, pretty sure. Attached by gdb, checked backtrace, continued execution, checked backtrace again. Here is it: https://gist.github.com/lstipakov/95e6091d53e8f779c14800e6309109c0 – lstipakov Aug 11 '16 at 08:40
  • @lstipakov, what is the `strace` output of your program when it hangs? – osgx Mar 11 '17 at 09:38

2 Answers2

0

Perhaps a more sure path is to use fread into a large buffer. The status file is small so allocate a local buffer and read the whole file.

Example look at the second answer for the simplest solution

This may still fail on the fopen or fread but a sensible error should be returned.

Community
  • 1
  • 1
Matthew Fisher
  • 2,258
  • 2
  • 14
  • 23
-2

/proc is a virtual filesystem. That means reading from "files" in it is not the same as reading from normal filesystem.

If process exits the information about it is removed from /proc much faster than if it was real filesystem (dirty cache flushing delay involved here).

Bearing that in mind imagine that process exits before you get to read next line which wasn't buffered yet.

The solution is either to account for file loss since you may not need information about process which does not exists anymore or buffer the entire file and then only parse it.

EDIT: the hang in process should clearly be related to the fact that this is virtual filesystem. It does not behave exactly same way as real filesystem. Since this is specific fs type the issue could be in fs driver. The code you provide looks fine for normal file reading.

Alexey Kamenskiy
  • 2,888
  • 5
  • 36
  • 56
  • Alex, what syscalls are made to read file from proc in the example from question? Are there several syscalls there? It will be safer to do one-time huge-enough read of the whole file (all-or-nothing) ant then parse from user buffer. – osgx Mar 11 '17 at 09:37