llvm.org GIT mirror llvm / 0ab591a
[raw_fd_ostream] report actual error in error messages Summary: Previously, we would emit error messages like "IO failure on output stream". This change causes use to include information about what actually went wrong, e.g. "No space left on device". Reviewers: sunfish, rnk Reviewed By: rnk Subscribers: mehdi_amini, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D39203 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316404 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Haarman 2 years ago
6 changed file(s) with 27 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
8787 std::string getErrorMessage() const;
8888
8989 /// \brief Set error and error message
90 void setError(std::error_code &EC, StringRef ErrorMsg = "") {
90 void setError(const std::error_code &EC, StringRef ErrorMsg = "") {
9191 Error = EC;
9292 ErrorDiagMsg = ErrorMsg.str();
9393 }
361361 int FD;
362362 bool ShouldClose;
363363
364 /// Error This flag is true if an error of any kind has been detected.
365 ///
366 bool Error;
364 std::error_code EC;
367365
368366 uint64_t pos;
369367
382380 size_t preferred_buffer_size() const override;
383381
384382 /// Set the flag indicating that an output error has been encountered.
385 void error_detected() { Error = true; }
383 void error_detected(std::error_code EC) { this->EC = EC; }
386384
387385 public:
388386 /// Open the specified file for writing. If an error occurs, information
423421
424422 bool has_colors() const override;
425423
424 std::error_code error() const { return EC; }
425
426426 /// Return the value of the flag in this raw_fd_ostream indicating whether an
427427 /// output error has been encountered.
428428 /// This doesn't implicitly flush any pending output. Also, it doesn't
429429 /// guarantee to detect all errors unless the stream has been closed.
430 bool has_error() const {
431 return Error;
432 }
430 bool has_error() const { return bool(EC); }
433431
434432 /// Set the flag read by has_error() to false. If the error flag is set at the
435433 /// time when this raw_ostream's destructor is called, report_fatal_error is
440438 /// Unless explicitly silenced."
441439 /// - from The Zen of Python, by Tim Peters
442440 ///
443 void clear_error() {
444 Error = false;
445 }
441 void clear_error() { EC = std::error_code(); }
446442 };
447443
448444 /// This returns a reference to a raw_ostream for standard output. Use it like:
275275 dest.close();
276276
277277 if (dest.has_error()) {
278 *ErrorMessage = strdup("Error printing to file");
278 std::string E = "Error printing to file: " + dest.error().message();
279 *ErrorMessage = strdup(E.c_str());
279280 return true;
280281 }
281282
217217 ToolOutputFile Out(Path, EC, sys::fs::F_None);
218218 if (EC) {
219219 std::string ErrMsg = "could not open bitcode file for writing: ";
220 ErrMsg += Path;
220 ErrMsg += Path.str() + ": " + EC.message();
221221 emitError(ErrMsg);
222222 return false;
223223 }
228228
229229 if (Out.os().has_error()) {
230230 std::string ErrMsg = "could not write bitcode file: ";
231 ErrMsg += Path;
231 ErrMsg += Path.str() + ": " + Out.os().error().message();
232232 emitError(ErrMsg);
233233 Out.os().clear_error();
234234 return false;
259259 bool genResult = compileOptimized(&objFile.os());
260260 objFile.os().close();
261261 if (objFile.os().has_error()) {
262 emitError((Twine("could not write object file: ") + Filename).str());
262 emitError((Twine("could not write object file: ") + Filename + ": " +
263 objFile.os().error().message())
264 .str());
263265 objFile.os().clear_error();
264266 sys::fs::remove(Twine(Filename));
265267 return false;
200200 Out.close();
201201
202202 if (Out.has_error()) {
203 // We failed to write out PID, so make up an excuse, remove the
203 // We failed to write out PID, so report the error, remove the
204204 // unique lock file, and fail.
205 auto EC = make_error_code(errc::no_space_on_device);
206205 std::string S("failed to write to ");
207206 S.append(UniqueLockFileName.str());
208 setError(EC, S);
207 setError(Out.error(), S);
209208 sys::fs::remove(UniqueLockFileName);
210209 return;
211210 }
516516 /// FD is the file descriptor that this writes to. If ShouldClose is true, this
517517 /// closes the file when the stream is destroyed.
518518 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
519 : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose),
520 Error(false) {
519 : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose) {
521520 if (FD < 0 ) {
522521 ShouldClose = false;
523522 return;
551550 raw_fd_ostream::~raw_fd_ostream() {
552551 if (FD >= 0) {
553552 flush();
554 if (ShouldClose && sys::Process::SafelyCloseFileDescriptor(FD))
555 error_detected();
553 if (ShouldClose) {
554 if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
555 error_detected(EC);
556 }
556557 }
557558
558559 #ifdef __MINGW32__
568569 // has_error() and clear the error flag with clear_error() before
569570 // destructing raw_ostream objects which may have errors.
570571 if (has_error())
571 report_fatal_error("IO failure on output stream.", /*GenCrashDiag=*/false);
572 report_fatal_error("IO failure on output stream: " + error().message(),
573 /*GenCrashDiag=*/false);
572574 }
573575
574576 void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
612614 continue;
613615
614616 // Otherwise it's a non-recoverable error. Note it and quit.
615 error_detected();
617 error_detected(std::error_code(errno, std::generic_category()));
616618 break;
617619 }
618620
628630 assert(ShouldClose);
629631 ShouldClose = false;
630632 flush();
631 if (sys::Process::SafelyCloseFileDescriptor(FD))
632 error_detected();
633 if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
634 error_detected(EC);
633635 FD = -1;
634636 }
635637
644646 pos = ::lseek(FD, off, SEEK_SET);
645647 #endif
646648 if (pos == (uint64_t)-1)
647 error_detected();
649 error_detected(std::error_code(errno, std::generic_category()));
648650 return pos;
649651 }
650652