1

I was wondering whether it would be legit to allocate a buffer for stdio stream buffering and use it with setvbuf (before fork), where the buffer is an anonymous mmap-"allocated" piece of memory shared between parent and child process?

Assuming the two are synchronized, am I allowed to assume that the outcome will be something sane, or should I rather avoid this at all costs?

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
  • I think this would also require interprocess mutexes, which I don't know that stdio would use. Just a thought though - I've no idea :). – FatalError Apr 07 '14 at 18:39

2 Answers2

3

You should not do this. Your C library will assume that the process has exclusive access to the standard IO buffer area, and will only mediate between threads of that process, no doubt using a mutex not in anonymous mmap. So you risk undefined behaviour if that buffer space is altered, just as if you wrote over it yourself.

However, a better question is why on earth would you want to do this? Why not make the buffer area /not/ shared (e.g. by using malloc() to allocate it), then everything will work fine.

abligh
  • 24,573
  • 4
  • 47
  • 84
  • Not sure it's a better question you pose. You are assuming I have no reason, but I do. Upvoting and accepting anyway. Thanks. It's sufficient to know that I should avoid it. And besides, the parent will *not* change the buffer while the child may. This is why this question makes sense in the first place (and the situation I refer to in the second paragraph). – 0xC0000022L Apr 07 '14 at 19:43
  • It's a better question because I can't think of a circumstance where it would be useful, and hence am interested in what you have in mind. – abligh Apr 07 '14 at 19:49
  • The code that forks is guarding a particular piece of code. If the buffers could be properly shared between parent and child I'd be able to simply continue outputting to the stdio streams I have open from the parent. Since this is not the case, I cannot (because it might intersperse output or in the worst case corrupt something for either process). – 0xC0000022L Apr 07 '14 at 20:31
  • Best either to use a thread (if you don't `exec`) or do it the hard way with pipes. – abligh Apr 07 '14 at 21:01
  • re: threads ... it would still crash. The point is that this is to stress and test some core code. Crashes are expected/anticipated (I am also building this with AddressSanitizer among other things). So it's much better to fork to another process that does not affect the parent when crashing. Yep, pipes it is now. I had hoped for a more trivial solution, though. Thanks again. – 0xC0000022L Apr 08 '14 at 10:18
  • Threads should not crash if stdio is thread safe. This is implementation dependent: http://stackoverflow.com/questions/467938/stdout-thread-safe-in-c-on-linux – abligh Apr 08 '14 at 10:30
  • the crashes obviously do not depend on stdio, but on the "guarded" code which gets to run inside the child process ;) – 0xC0000022L Apr 08 '14 at 19:40
1

That depends on where your implementation of the C library stores the control information managing the buffer.

If all control information that is used to control concurrent writing from threads is stored within the buffer itself, everything might work fine.

However, if that control information is stored somewhere else, it will be duplicated between the processes. The libc instances in the two different processes will not realize when the other process has written to the buffer or flushed it, and chaos will ensue.

Even if your libc implementation does work fine with this setup, I would strongly advise against it. After all, the semantic of setvbuf() is to set a buffer, not storage for buffer control information.

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106