This happens in dbus make check, but I don't have a small test case yet. I
looked at the gcc code some but couldn't find where the struct bb -> filename field
is supposed to get filled in.
Error is: "arc profiling: Can't open output file (null)."
in libgcc2.c:1360 (__bb_exit_func)
A possible clue is that running the test suite is generating
e.g. dbus/.libs/dbus-connection.da instead of dbus/dbus-connection.da
(.da files have moved to .libs vs. gcc 3.2 they were alongside the source files)
Or in fact the .bbg files are *both* in the srcdir and in .libs, for only some
of my subdirectories, and the .da files are *only* in .libs for those directories.
The .da files are in the srcdir for other directories.
This is probably unrelated to the bug.
The "failed to open (null)" is probably because on any error the code in
__bb_exit_func sets filename = NULL, so will then proceed to fail to open (null)
on any subsequent invocation. The code should probably simply return immediately
if !ptr->filename as a starting fix, then one could at least read the real error
message, instead of printing "can't open (null)" over and over.
That said, something is wildly wrong; strace of my test suite reveals:
1477 open() of EACH .da file for a total of 70888 opens (and each
open is followed by a pile of seeks)
Trying to single-step through __bb_exit_func isn't going well, gcc debuginfo
doesn't help. gdb seems to get confused and doesn't find the debuginfo (and the
"step"/"next" commands simply hang).
hmm, but I get no non-(null) filename error message before the (null) starts.
Created attachment 95340 [details]
test case, compile with -fprofile-arcs -ftest-coverage
This looks pretty simple now that I debugged it. In libgcc2.c, if
"error || !merging" we set ptr->filename to NULL, and then for all
subsequent calls to __bb_exit_func() pass the null pointer to fopen().
What I don't understand is why in the !merging case ptr->filename is
set to NULL.
So two actions probably needed:
- understand why if !merging we disable future .da file writes
- cleanly if (!ptr->filename) continue; instead of passing the
null pointer to fopen()
Also, I may be missing something, but the code seems to try to acquire a lock
with fcntl() but blissfully ignore failure to obtain said lock. I have a patch
that will do something like "while (don't have the lock) sleep ()"
Moved upstream as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12711