PR jit/64206: delay cleanup of tempdir if the user has requested debuginfo
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 9 Jan 2015 17:01:04 +0000 (17:01 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Fri, 9 Jan 2015 17:01:04 +0000 (17:01 +0000)
gcc/jit/ChangeLog:
PR jit/64206
* docs/internals/test-hello-world.exe.log.txt: Update, the log now
shows tempdir creation/cleanup.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
* jit-logging.h (class gcc::jit::log_user): Add gcc::jit::tempdir
to the list of subclasses in the comment.
* jit-playback.c (gcc::jit::playback::context::context): Add a
comment clarifying when the tempdir gets cleaned up.
(gcc::jit::playback::context::compile): Pass the context's logger,
if any, to the tempdir.
(gcc::jit::playback::context::dlopen_built_dso): When creating the
gcc::jit::result, if GCC_JIT_BOOL_OPTION_DEBUGINFO is set, hand
over ownership of the tempdir to it.
* jit-result.c: Include "jit-tempdir.h".
(gcc::jit::result::result): Add tempdir param, saving it as
m_tempdir.
(gcc::jit::result::~result): Delete m_tempdir.
* jit-result.h (gcc::jit::result::result): Add tempdir param.
(gcc::jit::result::m_tempdir): New field.
* jit-tempdir.c (gcc::jit::tempdir::tempdir): Add logger param;
add JIT_LOG_SCOPE.
(gcc::jit::tempdir::create): Add JIT_LOG_SCOPE to log entry/exit,
and log m_path_template and m_path_tempdir.
(gcc::jit::tempdir::~tempdir): Add JIT_LOG_SCOPE to log
entry/exit, and log the unlink and rmdir calls.
* jit-tempdir.h: Include "jit-logging.h".
(class gcc::jit::tempdir): Make this be a subclass of log_user.
(gcc::jit::tempdir::tempdir): Add logger param.
* notes.txt: Update to show the two possible places where the
tempdir can be cleaned up.

From-SVN: r219395

gcc/jit/ChangeLog
gcc/jit/docs/_build/texinfo/libgccjit.texi
gcc/jit/docs/internals/test-hello-world.exe.log.txt
gcc/jit/jit-logging.h
gcc/jit/jit-playback.c
gcc/jit/jit-result.c
gcc/jit/jit-result.h
gcc/jit/jit-tempdir.c
gcc/jit/jit-tempdir.h
gcc/jit/notes.txt

index 796c8a1c8ce42ad4602277fbae57d366ab9421a0..9dc133ed3ffd650bee5c4edfdaa778321269888c 100644 (file)
@@ -1,3 +1,36 @@
+2015-01-09  David Malcolm  <dmalcolm@redhat.com>
+
+       PR jit/64206
+       * docs/internals/test-hello-world.exe.log.txt: Update, the log now
+       shows tempdir creation/cleanup.
+       * docs/_build/texinfo/libgccjit.texi: Regenerate.
+       * jit-logging.h (class gcc::jit::log_user): Add gcc::jit::tempdir
+       to the list of subclasses in the comment.
+       * jit-playback.c (gcc::jit::playback::context::context): Add a
+       comment clarifying when the tempdir gets cleaned up.
+       (gcc::jit::playback::context::compile): Pass the context's logger,
+       if any, to the tempdir.
+       (gcc::jit::playback::context::dlopen_built_dso): When creating the
+       gcc::jit::result, if GCC_JIT_BOOL_OPTION_DEBUGINFO is set, hand
+       over ownership of the tempdir to it.
+       * jit-result.c: Include "jit-tempdir.h".
+       (gcc::jit::result::result): Add tempdir param, saving it as
+       m_tempdir.
+       (gcc::jit::result::~result): Delete m_tempdir.
+       * jit-result.h (gcc::jit::result::result): Add tempdir param.
+       (gcc::jit::result::m_tempdir): New field.
+       * jit-tempdir.c (gcc::jit::tempdir::tempdir): Add logger param;
+       add JIT_LOG_SCOPE.
+       (gcc::jit::tempdir::create): Add JIT_LOG_SCOPE to log entry/exit,
+       and log m_path_template and m_path_tempdir.
+       (gcc::jit::tempdir::~tempdir): Add JIT_LOG_SCOPE to log
+       entry/exit, and log the unlink and rmdir calls.
+       * jit-tempdir.h: Include "jit-logging.h".
+       (class gcc::jit::tempdir): Make this be a subclass of log_user.
+       (gcc::jit::tempdir::tempdir): Add logger param.
+       * notes.txt: Update to show the two possible places where the
+       tempdir can be cleaned up.
+
 2015-01-08  David Malcolm  <dmalcolm@redhat.com>
 
        * libgccjit.h (struct gcc_jit_context): Rewrite the descriptive
index d489d46527a3ef728e44fa11a7718552b78a8202..4c9e2ba6e3fc2d0b62a486e3c7ff59c96e582299 100644 (file)
@@ -19,7 +19,7 @@
 
 @copying
 @quotation
-libgccjit 5.0.0 (experimental 20150108), January 08, 2015
+libgccjit 5.0.0 (experimental 20150109), January 09, 2015
 
 David Malcolm
 
@@ -12468,9 +12468,12 @@ Client Code   . Generated .            libgccjit.so
               .           .    │     .               .
               .           .    │ playback::context dtor
               .           .     ──>  .               .
-              .           .       │ Cleanup tempdir  .
+              .           .       │ Normally we cleanup the tempdir here:
               .           .       │   ("fake.so" is unlinked from the
               .           .       │    filesystem at this point)
+              .           .       │ If the client code requested debuginfo, the
+              .           .       │ cleanup happens later (in gcc_jit_result_release)
+              .           .       │ to make it easier on the debugger (see PR jit/64206)
               .           .    <──   .               .
               .           .    │     .               .
               .           .    │ end of recording::context::compile ()
@@ -12494,6 +12497,10 @@ etc│          .           .          .               .
     ──────────────────────────>      .               .
               .           .    │ dlclose () the loaded DSO
               .           .    │    (code becomes uncallable)
+              .           .    │     .               .
+              .           .    │ If the client code requested debuginfo, then
+              .           .    │ cleanup of the tempdir was delayed.
+              .           .    │ If that was the case, clean it up now.
    <───────────────────────────      .               .
    │          .           .          .               .
 
@@ -12621,6 +12628,12 @@ JIT:   exiting: void gcc::jit::recording::context::validate()
 JIT:   entering: gcc::jit::playback::context::context(gcc::jit::recording::context*)
 JIT:   exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*)
 JIT:   entering: gcc::jit::result* gcc::jit::playback::context::compile()
+JIT:    entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
+JIT:    exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
+JIT:    entering: bool gcc::jit::tempdir::create()
+JIT:     m_path_template: /tmp/libgccjit-XXXXXX
+JIT:     m_path_tempdir: /tmp/libgccjit-CKq1M9
+JIT:    exiting: bool gcc::jit::tempdir::create()
 JIT:    entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
 JIT:    exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
 JIT:    entering: void gcc::jit::playback::context::acquire_mutex()
@@ -12671,8 +12684,9 @@ JIT:     argv[5]: -fno-use-linker-plugin
 JIT:     argv[6]: (null)
 JIT:    exiting: void gcc::jit::playback::context::convert_to_dso(const char*)
 JIT:    entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
-JIT:     entering: gcc::jit::result::result(gcc::jit::logger*, void*)
-JIT:     exiting: gcc::jit::result::result(gcc::jit::logger*, void*)
+JIT:     GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result
+JIT:     entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
+JIT:     exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
 JIT:    exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
 JIT:    entering: void gcc::jit::playback::context::release_mutex()
 JIT:    exiting: void gcc::jit::playback::context::release_mutex()
@@ -12696,6 +12710,11 @@ JIT: exiting: gcc_jit_context_release
 JIT: entering: gcc_jit_result_release
 JIT:  deleting result: 0x12f75d0
 JIT:  entering: virtual gcc::jit::result::~result()
+JIT:   entering: gcc::jit::tempdir::~tempdir()
+JIT:    unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s
+JIT:    unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so
+JIT:    removing tempdir: /tmp/libgccjit-CKq1M9
+JIT:   exiting: gcc::jit::tempdir::~tempdir()
 JIT:  exiting: virtual gcc::jit::result::~result()
 JIT: exiting: gcc_jit_result_release
 JIT: gcc::jit::logger::~logger()
index a96d80fc45e70076c94a714d1f671ea0cc9efa43..113dc351297bdc604647de1954b2470a961df546 100644 (file)
@@ -46,6 +46,12 @@ JIT:   exiting: void gcc::jit::recording::context::validate()
 JIT:   entering: gcc::jit::playback::context::context(gcc::jit::recording::context*)
 JIT:   exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*)
 JIT:   entering: gcc::jit::result* gcc::jit::playback::context::compile()
+JIT:    entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
+JIT:    exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
+JIT:    entering: bool gcc::jit::tempdir::create()
+JIT:     m_path_template: /tmp/libgccjit-XXXXXX
+JIT:     m_path_tempdir: /tmp/libgccjit-CKq1M9
+JIT:    exiting: bool gcc::jit::tempdir::create()
 JIT:    entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
 JIT:    exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
 JIT:    entering: void gcc::jit::playback::context::acquire_mutex()
@@ -96,8 +102,9 @@ JIT:     argv[5]: -fno-use-linker-plugin
 JIT:     argv[6]: (null)
 JIT:    exiting: void gcc::jit::playback::context::convert_to_dso(const char*)
 JIT:    entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
-JIT:     entering: gcc::jit::result::result(gcc::jit::logger*, void*)
-JIT:     exiting: gcc::jit::result::result(gcc::jit::logger*, void*)
+JIT:     GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result
+JIT:     entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
+JIT:     exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
 JIT:    exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
 JIT:    entering: void gcc::jit::playback::context::release_mutex()
 JIT:    exiting: void gcc::jit::playback::context::release_mutex()
@@ -121,6 +128,11 @@ JIT: exiting: gcc_jit_context_release
 JIT: entering: gcc_jit_result_release
 JIT:  deleting result: 0x12f75d0
 JIT:  entering: virtual gcc::jit::result::~result()
+JIT:   entering: gcc::jit::tempdir::~tempdir()
+JIT:    unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s
+JIT:    unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so
+JIT:    removing tempdir: /tmp/libgccjit-CKq1M9
+JIT:   exiting: gcc::jit::tempdir::~tempdir()
 JIT:  exiting: virtual gcc::jit::result::~result()
 JIT: exiting: gcc_jit_result_release
 JIT: gcc::jit::logger::~logger()
index 581090c738ad680c9a2808c53348d995c7bec944..48f223de98160c9ffabffdefad432eb5688857af 100644 (file)
@@ -112,6 +112,8 @@ log_scope::~log_scope ()
 
       - class gcc::jit::playback::context
 
+      - class gcc::jit::tempdir
+
       - class gcc::jit::result
 
    The log_user class keeps the reference-count of a logger up-to-date.  */
index a8a281a66843fb27bd562805d739744e056658ab..401977827c408bb383c701b125f1bd1ce756ccf9 100644 (file)
@@ -104,8 +104,18 @@ playback::context::context (recording::context *ctxt)
 playback::context::~context ()
 {
   JIT_LOG_SCOPE (get_logger ());
-  if (m_tempdir)
-    delete m_tempdir;
+
+  /* Normally the playback::context is responsible for cleaning up the
+     tempdir (including "fake.so" within the filesystem).
+
+     In the normal case, clean it up now.
+
+     However m_tempdir can be NULL if the context has handed over
+     responsibility for the tempdir cleanup to the jit::result object, so
+     that the cleanup can be delayed (see PR jit/64206).  If that's the
+     case this "delete NULL;" is a no-op. */
+  delete m_tempdir;
+
   m_functions.release ();
 }
 
@@ -1554,7 +1564,7 @@ compile ()
   int keep_intermediates =
     get_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES);
 
-  m_tempdir = new tempdir (keep_intermediates);
+  m_tempdir = new tempdir (get_logger (), keep_intermediates);
   if (!m_tempdir->create ())
     return NULL;
 
@@ -1935,7 +1945,37 @@ dlopen_built_dso ()
     add_error (NULL, "%s", error);
   }
   if (handle)
-    result_obj = new result (get_logger (), handle);
+    {
+      /* We've successfully dlopened the result; create a
+        jit::result object to wrap it.
+
+        We're done with the tempdir for now, but if the user
+        has requested debugging, the user's debugger might not
+        be capable of dealing with the .so file being unlinked
+        immediately, so keep it around until after the result
+        is released.  We do this by handing over ownership of
+        the jit::tempdir to the result.  See PR jit/64206.  */
+      tempdir *handover_tempdir;
+      if (get_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO))
+       {
+         handover_tempdir = m_tempdir;
+         m_tempdir = NULL;
+         /* The tempdir will eventually be cleaned up in the
+            jit::result's dtor. */
+         log ("GCC_JIT_BOOL_OPTION_DEBUGINFO was set:"
+              " handing over tempdir to jit::result");
+       }
+      else
+       {
+         handover_tempdir = NULL;
+         /* ... and retain ownership of m_tempdir so we clean it
+            up it the playback::context's dtor. */
+         log ("GCC_JIT_BOOL_OPTION_DEBUGINFO was not set:"
+              " retaining ownership of tempdir");
+       }
+
+      result_obj = new result (get_logger (), handle, handover_tempdir);
+    }
   else
     result_obj = NULL;
 
index 67699e0b19809e829ab5d1ce3b2b6126469ec02a..a9330e591c53d034e42f4219706f0581254af4a9 100644 (file)
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-common.h"
 #include "jit-logging.h"
 #include "jit-result.h"
+#include "jit-tempdir.h"
 
 namespace gcc {
 namespace jit {
@@ -32,9 +33,10 @@ namespace jit {
 /* Constructor for gcc::jit::result.  */
 
 result::
-result(logger *logger, void *dso_handle) :
+result(logger *logger, void *dso_handle, tempdir *tempdir_) :
   log_user (logger),
-  m_dso_handle (dso_handle)
+  m_dso_handle (dso_handle),
+  m_tempdir (tempdir_)
 {
   JIT_LOG_SCOPE (get_logger ());
 }
@@ -48,6 +50,13 @@ result::~result()
   JIT_LOG_SCOPE (get_logger ());
 
   dlclose (m_dso_handle);
+
+  /* Responsibility for cleaning up the tempdir (including "fake.so" within
+     the filesystem) might have been handed to us by the playback::context,
+     so that the cleanup can be delayed (see PR jit/64206).
+
+     If so, clean it up now.  */
+  delete m_tempdir;
 }
 
 /* Attempt to locate the given function by name within the
index 59d28a1a364474c9ddce958263783e4ededecfa3..d9073f2694512a938a59a0efbaa45bced0fc0501 100644 (file)
@@ -29,7 +29,7 @@ namespace jit {
 class result : public log_user
 {
 public:
-  result(logger *logger, void *dso_handle);
+  result(logger *logger, void *dso_handle, tempdir *tempdir_);
 
   virtual ~result();
 
@@ -38,6 +38,7 @@ public:
 
 private:
   void *m_dso_handle;
+  tempdir *m_tempdir;
 };
 
 } // namespace gcc::jit
index 14c7418469db58440588521e5a23126d09aaebb7..856b2469b4fd2575c08ffb4a385f402b460c3e9e 100644 (file)
@@ -66,14 +66,16 @@ make_tempdir_path_template ()
 /* The constructor for the jit::tempdir object.
    The real work is done by the jit::tempdir::create method.  */
 
-gcc::jit::tempdir::tempdir (int keep_intermediates)
-  : m_keep_intermediates (keep_intermediates),
+gcc::jit::tempdir::tempdir (logger *logger, int keep_intermediates)
+  : log_user (logger),
+    m_keep_intermediates (keep_intermediates),
     m_path_template (NULL),
     m_path_tempdir (NULL),
     m_path_c_file (NULL),
     m_path_s_file (NULL),
     m_path_so_file (NULL)
 {
+  JIT_LOG_SCOPE (get_logger ());
 }
 
 /* Do the real work of creating the on-disk tempdir.
@@ -83,16 +85,22 @@ gcc::jit::tempdir::tempdir (int keep_intermediates)
 bool
 gcc::jit::tempdir::create ()
 {
+  JIT_LOG_SCOPE (get_logger ());
+
   m_path_template = make_tempdir_path_template ();
   if (!m_path_template)
     return false;
 
+  log ("m_path_template: %s", m_path_template);
+
   /* Create tempdir using mkdtemp.  This is created with 0700 perms and
      is unique.  Hence no other (non-root) users should have access to
      the paths within it.  */
   m_path_tempdir = mkdtemp (m_path_template);
   if (!m_path_tempdir)
     return false;
+  log ("m_path_tempdir: %s", m_path_tempdir);
+
   m_path_c_file = concat (m_path_tempdir, "/fake.c", NULL);
   m_path_s_file = concat (m_path_tempdir, "/fake.s", NULL);
   m_path_so_file = concat (m_path_tempdir, "/fake.so", NULL);
@@ -107,17 +115,28 @@ gcc::jit::tempdir::create ()
 
 gcc::jit::tempdir::~tempdir ()
 {
+  JIT_LOG_SCOPE (get_logger ());
+
   if (m_keep_intermediates)
     fprintf (stderr, "intermediate files written to %s\n", m_path_tempdir);
   else
     {
       /* Clean up .s/.so and tempdir. */
       if (m_path_s_file)
-        unlink (m_path_s_file);
+       {
+         log ("unlinking .s file: %s", m_path_s_file);
+         unlink (m_path_s_file);
+       }
       if (m_path_so_file)
-        unlink (m_path_so_file);
+       {
+         log ("unlinking .so file: %s", m_path_so_file);
+         unlink (m_path_so_file);
+       }
       if (m_path_tempdir)
-        rmdir (m_path_tempdir);
+       {
+         log ("removing tempdir: %s", m_path_tempdir);
+         rmdir (m_path_tempdir);
+       }
     }
 
   free (m_path_template);
index 49f686cc2a8b738cb28715b6047ca7ec8a2a643f..2553d72f924ec95e307dca36d56a5e447caced54 100644 (file)
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef JIT_TEMPDIR_H
 #define JIT_TEMPDIR_H
 
+#include "jit-logging.h"
+
 namespace gcc {
 
 namespace jit {
@@ -43,10 +45,10 @@ namespace jit {
   It is normally deleted from the filesystem in the playback::context's
   dtor, unless GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES was set.  */
 
-class tempdir
+class tempdir : public log_user
 {
  public:
-  tempdir (int keep_intermediates);
+  tempdir (logger *logger, int keep_intermediates);
   ~tempdir ();
 
   bool create ();
index 26f381e4177aec31ff3809dd898d2fe39313e7c1..7df4a7bdc4e80b7c3f9e4a105eff1be8a4e42b1a 100644 (file)
@@ -84,9 +84,12 @@ Client Code   . Generated .            libgccjit.so
               .           .    │     .               .
               .           .    │ playback::context dtor
               .           .     ──>  .               .
-              .           .       │ Cleanup tempdir  .
+              .           .       │ Normally we cleanup the tempdir here:
               .           .       │   ("fake.so" is unlinked from the
               .           .       │    filesystem at this point)
+              .           .       │ If the client code requested debuginfo, the
+              .           .       │ cleanup happens later (in gcc_jit_result_release)
+              .           .       │ to make it easier on the debugger (see PR jit/64206)
               .           .    <──   .               .
               .           .    │     .               .
               .           .    │ end of recording::context::compile ()
@@ -110,5 +113,9 @@ etc│          .           .          .               .
     ──────────────────────────>      .               .
               .           .    │ dlclose () the loaded DSO
               .           .    │    (code becomes uncallable)
+              .           .    │     .               .
+              .           .    │ If the client code requested debuginfo, then
+              .           .    │ cleanup of the tempdir was delayed.
+              .           .    │ If that was the case, clean it up now.
    <───────────────────────────      .               .
    │          .           .          .               .