https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124506

            Bug ID: 124506
           Summary: gcc/lockfile{.h,.cc} is buggy and leaking fd, solution
                    + windows support is here
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: lto
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jkl9543 at 163 dot com
  Target Milestone: ---

Created attachment 63934
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=63934&action=edit
fixed gcc/lock_file{.h,.cc} and original version (15.2)

== Module and Related file ==

Module: lto (lto-wrapper);

Related file: gcc/lockfile.cc and gcc/lockfile.h;


== What will this report archive ==

1. Solve file descriptor leaking problem of gcc/lockfile{.h,.cc};

2. Support for windows platform and so removes mingw-gcc 'lto-wrapper.exe:
warning: using ltrans cache without file locking support, do not use in
parallel'.


== What's wrong with current lockfile ==

1. File descriptor fd is leaked when calling these methods of class lockfile:
   lockfile::lock_write() lockfile::try_lock_write(), lockfile::lock_read().

   These methods all have 'fd = open(...)' on the first line of their function
body, without checking existing 'fd >= 0'. And it is observed that first
'item->lock.lock_write()' => then 'item->lock.lock_read()' is happen in
run_gcc() of 'gcc/lto-wrapper.cc';

   _suggestion_: just _reuse_ the fd if 'fd >= 0'.

2. The function is wrong in gcc/lockfile.cc:
   void lockfile::unlock ()
   {
     if (fd < 0) //_BUG_: should be 'fd >= 0'
     {
       ...
       close (fd);
       fd = -1;
     }
   }
   _suggestion_: change 'fd < 0' to 'fd >= 0';

3. In gcc/lockfile.h: class lockfile is missing a destructor which may also
lead to file descriptor leak.

    _suggestion_: add destructor ~lockfile(){ if(fd>=0) unlock(); }

4. Also in gcc/lockfile.h: bool locked(){ return fd<0; }

    the method name looks good but the function looks weired and even
misleading (e.g. locked()==false when lock_read() or lock_write() returns
success; newly_constructed_lock_file.locked()==true).

    _suggestion_: remove this method; because it is never used/referenced and
seems make no sense.

5. Locking is unimplemented for windows platform, makes mingw gcc
'lto-wrapper.exe: warning: using ltrans cache without file locking support, do
not use in parallel'.

   The locking functions using fcntl(F_SETLKW) with
flock.l_type={F_WRLCK,F_RDLCK,F_UNLCK} are perfectly mapped to windows API
(LockFileEx() and UnlockFileEx()). So it is easy to implement locking support
for windows: just call LockFileEx(_get_osfhandle(fd),...); I have already
patched 'lto-wrapper.exe' for mingw-gcc, and it works well.


== What is in attachment ==
  The attachment includes _fixed_ gcc/lock_file{.h,.cc} that solves all above
problems, for reference.

Reply via email to