Problem on exception and laziness

Hi, I am aware that laziness sometimes may cause exception handling in unexpected ways. Recently I have such a problem that I cannot figure out how to fix (simply). I have a function `watch` that parse the content of /proc/. And I use `catch` to wrap `readFile` call, since the data in /proc/ could be gone any time. ```Haskell wrap2Maybe :: IO a -> IO (Maybe a) wrap2Maybe f = catch ((<$>) Just $! f) (\(_ :: IOException) -> return Nothing) watch args = do mStat <- wrap2Maybe (readFile ("/proc/" > fp > "stat")) >>= return . flip (>>=) parseStat print mStat watch args ``` But occasionally, my tool exits with message: GoM: /proc/1484/stat: hGetContents: does not exist (No such process) Since above code is the only `readFile` call which leads to hGetContents, I could not figure out what else should I do to catch the error. -- 竹密岂妨流水过 山高哪阻野云飞

At a guess, include the parseStat in the wrap2Maybe so that the input is evaluated. Alternately, force the spine of the list produced by readFile so that the entire file is read immediately. Note that the error is from getContents, which produces a lazy list that reads "in the background" as the resulting list is consumed (see unsafeInterleaveIO): "files" in /proc are generated as they are read, so if a process exits while you have an open handle on one of its files in /proc, it will be invalidated on you like that. On Tue, Apr 23, 2019 at 2:01 AM Magicloud Magiclouds < magicloud.magiclouds@gmail.com> wrote:
Hi, I am aware that laziness sometimes may cause exception handling in unexpected ways. Recently I have such a problem that I cannot figure out how to fix (simply).
I have a function `watch` that parse the content of /proc/. And I use `catch` to wrap `readFile` call, since the data in /proc/ could be gone any time.
```Haskell wrap2Maybe :: IO a -> IO (Maybe a) wrap2Maybe f = catch ((<$>) Just $! f) (\(_ :: IOException) -> return Nothing)
watch args = do mStat <- wrap2Maybe (readFile ("/proc/" > fp > "stat")) >>= return . flip (>>=) parseStat print mStat watch args ```
But occasionally, my tool exits with message: GoM: /proc/1484/stat: hGetContents: does not exist (No such process)
Since above code is the only `readFile` call which leads to hGetContents, I could not figure out what else should I do to catch the error. -- 竹密岂妨流水过 山高哪阻野云飞 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com

Thanks. I thought $! could help on this, so tried to avoid DeepSeq. Let me try.
On Tue, Apr 23, 2019 at 2:06 PM Brandon Allbery
At a guess, include the parseStat in the wrap2Maybe so that the input is evaluated. Alternately, force the spine of the list produced by readFile so that the entire file is read immediately.
Note that the error is from getContents, which produces a lazy list that reads "in the background" as the resulting list is consumed (see unsafeInterleaveIO): "files" in /proc are generated as they are read, so if a process exits while you have an open handle on one of its files in /proc, it will be invalidated on you like that.
On Tue, Apr 23, 2019 at 2:01 AM Magicloud Magiclouds
wrote: Hi, I am aware that laziness sometimes may cause exception handling in unexpected ways. Recently I have such a problem that I cannot figure out how to fix (simply).
I have a function `watch` that parse the content of /proc/. And I use `catch` to wrap `readFile` call, since the data in /proc/ could be gone any time.
```Haskell wrap2Maybe :: IO a -> IO (Maybe a) wrap2Maybe f = catch ((<$>) Just $! f) (\(_ :: IOException) -> return Nothing)
watch args = do mStat <- wrap2Maybe (readFile ("/proc/" > fp > "stat")) >>= return . flip (>>=) parseStat print mStat watch args ```
But occasionally, my tool exits with message: GoM: /proc/1484/stat: hGetContents: does not exist (No such process)
Since above code is the only `readFile` call which leads to hGetContents, I could not figure out what else should I do to catch the error. -- 竹密岂妨流水过 山高哪阻野云飞 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com
-- 竹密岂妨流水过 山高哪阻野云飞 And for G+, please use magiclouds#gmail.com.

It's /proc that is messing you up here, I suspect: it's regenerated on every read system call, not on open, so if it's more than one block then it can go away between reading the blocks because there's nothing to generate the next block from. Flip side, because of this most files in /proc are kept small, so it's safe to read them all at once. (Memory images being an exception, but those are handled differently anyway.) Moral of the story is you should probably use strict I/O with stuff under /proc, not (h)getContents or anything based on it like readFile. On Tue, Apr 23, 2019 at 2:50 AM Magicloud Magiclouds < magicloud.magiclouds@gmail.com> wrote:
Thanks. I thought $! could help on this, so tried to avoid DeepSeq. Let me try.
On Tue, Apr 23, 2019 at 2:06 PM Brandon Allbery
wrote: At a guess, include the parseStat in the wrap2Maybe so that the input is
evaluated. Alternately, force the spine of the list produced by readFile so that the entire file is read immediately.
Note that the error is from getContents, which produces a lazy list that
reads "in the background" as the resulting list is consumed (see unsafeInterleaveIO): "files" in /proc are generated as they are read, so if a process exits while you have an open handle on one of its files in /proc, it will be invalidated on you like that.
On Tue, Apr 23, 2019 at 2:01 AM Magicloud Magiclouds <
magicloud.magiclouds@gmail.com> wrote:
Hi, I am aware that laziness sometimes may cause exception handling in unexpected ways. Recently I have such a problem that I cannot figure out how to fix (simply).
I have a function `watch` that parse the content of /proc/. And I use `catch` to wrap `readFile` call, since the data in /proc/ could be gone any time.
```Haskell wrap2Maybe :: IO a -> IO (Maybe a) wrap2Maybe f = catch ((<$>) Just $! f) (\(_ :: IOException) -> return
Nothing)
watch args = do mStat <- wrap2Maybe (readFile ("/proc/" > fp > "stat")) >>= return . flip (>>=) parseStat print mStat watch args ```
But occasionally, my tool exits with message: GoM: /proc/1484/stat: hGetContents: does not exist (No such process)
Since above code is the only `readFile` call which leads to hGetContents, I could not figure out what else should I do to catch the error. -- 竹密岂妨流水过 山高哪阻野云飞 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com
-- 竹密岂妨流水过 山高哪阻野云飞
And for G+, please use magiclouds#gmail.com.
-- brandon s allbery kf8nh allbery.b@gmail.com
participants (2)
-
Brandon Allbery
-
Magicloud Magiclouds