We are developing a tool for data safety checking, and observed a possible bug in QEditor (used in the Texstudio). We found the following system-call trace:
[pid 18857] write(26, "1111111111111111111\n", 20) = 20 ---> backup file
[pid 18857] _llseek(26, 0, [0], SEEK_SET) = 0
[pid 18857] close(26) = 0
[pid 18857] rename("/tmp/qt_temp.z18857", "/tmp/a.tex~txs0") = 0
[pid 18857] open("/tmp/a.tex", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE|O_CLOEXEC, 0666) = 24
[pid 18857] unlink("/tmp/a.tex~txs0") = 0
[pid 18857] write(24, "1111111111111111111\n111111111111"..., 61) = 61
[pid 18857] close(24) = 0
The open with O_TRUNC truncates the file size to be zero. If the program terminates/system crashes after unlink(), the file contents will be gone forever.
We also checked the source code (QEditor::save, which calls QEditor::saveCopy), but the source code seems first writes to the contents, then deletes the file. I'm not sure why this code produces the above system-call trace (you may also check it by strace).
If you intended to use deletion, we suggest synchronize (e.g., fdatasync) to protect data, because if you do
(1) write data fo F1
(2) delete F2
and at this time system crashes, in the recovered file-system, F2 can be deleted and data is not reached to F1 (both F1 and F2 are lost). A paper FYI: https://www.usenix.org/node/186195 (explains the reordering).
Version: 2.10.8 5082:5ee1d0
p.s. QSaveFile provides a protable and safe solution, but only availble for Qt5.
Thank you for your attetion!
Thanks for the notification.
We've migrated to QSaveFile for Qt5, which will cover the majority of users.
For Qt4, we'll leave it as is, since the source code does the things in the correct order and digging into the low level calls to find why (and under which conditions) the system-call trace looks as above would be a major effort, which is not worth it.