Do not use stdio for buffered I/O

Authored by mwolff on Apr 24 2018, 8:50 PM.

Description

Do not use stdio for buffered I/O

Instead, implement a custom buffer scheme that uses snprintf
and write directly. This way, we have the write syscall under
total control and can properly handle EINTR. See also:

http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2006-05/msg00314.html

This seems to fix the issue where the data file is corrupted. It
seems to be due to a SIGCHLD signal being received while we were
inside an fprintf syscall:

perf trace --no-syscalls record -m 16M \
-e signal:signal_deliver \
-e signal:signal_generate \

-e sched:sched_process_exit \

--call-graph dwarf \
./AppRun -s test
...

  1. child process of kdevelop exits: 2443.428 sched:sched_process_exit:comm=docker pid=15924 prio=120
  2. SIGCHILD is handled by a thread that's inside fprintf: 2444.617 signal:signal_deliver:sig=17 errno=0 code=1 sa_handler=7fa121163570 sa_flags=4000005 get_signal ([kernel.kallsyms]) GI_libc_write (/usr/lib/libc-2.26.so) _IO_new_file_write (inlined) new_do_write (/usr/lib/libc-2.26.so) _IO_new_do_write (inlined) _IO_new_file_xsputn (inlined) _IO_vfprintf_internal (inlined) ___fprintf_chk (inlined) fprintf (inlined) writeLine<long unsigned int, unsigned int, long unsigned int> (inlined) handleMalloc (inlined) ...
  3. eventually heaptrack_interpret receives partially written data:

    failed to parse line: t 7fa11060b9- 30a09e0 heaptrack stats: allocations: 534879 leaked allocations: 150033 temporary allocations: 78765
  4. and then exists: 3580.135 sched:sched_process_exit:comm=heaptrack_inter pid=15913 prio=120
  5. leading to a SIGPIPE: 3580.628 signal:signal_generate:sig=13 errno=0 code=0 comm=kdevelop pid=15915 grp=0 res=1 send_signal ([kernel.kallsyms]) send_signal ([kernel.kallsyms]) GI_libc_write (/usr/lib/libc-2.26.so) _IO_new_file_write (inlined) new_do_write (/usr/lib/libc-2.26.so) _IO_new_do_write (inlined) _IO_new_file_xsputn (inlined) _IO_vfprintf_internal (inlined) ___fprintf_chk (inlined) fprintf (inlined) writeLine<char const*, long unsigned int> (inlined)

It seems to me as if this is the explanation for this issue.
Ultimately it boils down to fprintf not being save for use when
you may receive sigchild leading to EINTR.

BUG: 393387

Details

Committed
mwolffApr 27 2018, 11:18 AM
Parents
R45:fc4b7ef99d3b: Optionally add helgrind annotations to the custom SpinLock
Branches
Unknown
Tags
Unknown