You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by jo...@apache.org on 2020/04/03 16:14:43 UTC

[impala] branch master updated: IMPALA-9571: Fix Impala crash from unexpected boost filesystem_error exception

This is an automated email from the ASF dual-hosted git repository.

joemcdonnell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git


The following commit(s) were added to refs/heads/master by this push:
     new 7606133  IMPALA-9571: Fix Impala crash from unexpected boost filesystem_error exception
7606133 is described below

commit 76061331781e67b90d7750abadfaf8b013dc64a5
Author: Joe McDonnell <jo...@cloudera.com>
AuthorDate: Thu Apr 2 15:19:42 2020 -0700

    IMPALA-9571: Fix Impala crash from unexpected boost filesystem_error exception
    
    The no-exception signature of boost::filesystem::remove_all() has a
    longstanding bug where it can throw an exception even for the
    no-exceptions interface. Boost recently added the "noexcept" specifier
    to the no-exception signature of remove_all(). When a "noexcept"
    function throws an exception, it causes the program to call std::terminate()
    which aborts the program. This makes the try/catch block around
    remove_all() useless.
    
    As a point fix, this switches FilesystemUtil to use the remove_all()
    signature that can throw exceptions. This code already had a try/catch
    block around remove_all(), so now it just uses that to get the error
    code.
    
    Newer versions of boost (1.63+) fix the underlying problem, so this
    code can be removed when we upgrade boost.
    
    Testing:
     - Ran core tests
     - Ran FilesystemUtil backend test
    
    Change-Id: I23016f37401604fc41fc99c0a056439a31333e3f
    Reviewed-on: http://gerrit.cloudera.org:8080/15640
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
    Reviewed-by: Csaba Ringhofer <cs...@cloudera.com>
---
 be/src/util/filesystem-util.cc | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/be/src/util/filesystem-util.cc b/be/src/util/filesystem-util.cc
index 5ec1755..83c3c90 100644
--- a/be/src/util/filesystem-util.cc
+++ b/be/src/util/filesystem-util.cc
@@ -87,10 +87,16 @@ Status FileSystemUtil::RemoveAndCreateDirectory(const string& directory) {
     // the check for existence above and the removal here. If the directory is removed in
     // this window, we may get "no_such_file_or_directory" error which is fine.
     //
-    // There is a bug in boost library (as of version 1.6) which may lead to unexpected
-    // exceptions even though we are using the no-exceptions interface. See IMPALA-2846.
+    // There is a bug in boost library (as of version 1.61) which may lead to unexpected
+    // exceptions from the no-exceptions interface. Even worse, the no-exceptions
+    // interface is marked as noexcept, so the unexpected exception will cause the
+    // program to immediately call std::terminate(). This renders the try/catch block
+    // useless. For now, this uses the interface that can throw exceptions and
+    // gets the errorcode from the exception. See IMPALA-2846 + IMPALA-9571.
+    // TODO: Newer boost has a fix for this bug, so this can be switched back after
+    // upgrading boost.
     try {
-      filesystem::remove_all(directory, errcode);
+      filesystem::remove_all(directory);
     } catch (filesystem::filesystem_error& e) {
       errcode = e.code();
     }
@@ -111,10 +117,11 @@ Status FileSystemUtil::RemoveAndCreateDirectory(const string& directory) {
 Status FileSystemUtil::RemovePaths(const vector<string>& directories) {
   for (int i = 0; i < directories.size(); ++i) {
     error_code errcode;
-    // There is a bug in boost library (as of version 1.6) which may lead to unexpected
-    // exceptions even though we are using the no-exceptions interface. See IMPALA-2846.
+    // This uses the boost remove_all() interface that can throw exceptions to avoid a
+    // bug in the implementation of the no-exceptions remove_all(). See comment in
+    // RemoveAndCreateDirectory() for more details.
     try {
-      filesystem::remove_all(directories[i], errcode);
+      filesystem::remove_all(directories[i]);
     } catch (filesystem::filesystem_error& e) {
       errcode = e.code();
     }