Skip to content

Commit

Permalink
fix crash when fopen fails and fsetlocking attempts to use the result
Browse files Browse the repository at this point in the history
Fix the following crash when fopen fails on fifo creation. Heaptrack
cannot continue, but at least doesn't crash the target application.

```
 #0  0x00007f7031c9d428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
 #1  0x00007f7031c9f02a in __GI_abort () at abort.c:89
 #2  0x00007f7032180985 in PaCrashHandler (SigNum=11, Info=0x7fffe68479b0, Context=0x7fffe6847880) at /home/username/work/knight_project/knight_project/knight/lib/nv/modules/nvcore/source/pa/linux/exit.c:244
 #3  <signal handler called>
 #4  __GI___fsetlocking (fp=fp@entry=0x0, type=type@entry=2) at __fsetlocking.c:25
 #5  0x00007f6f7c9634e4 in (anonymous namespace)::createFile (fileName=0x1becf00 "/tmp/heaptrack_fifo14093") at /home/username/tmp/heaptrack/src/track/libheaptrack.cpp:187
 #6  (anonymous namespace)::HeapTrack::initialize (this=<synthetic pointer>, stopCallback=0x7f6f7c95ef80 <<lambda()>::_FUN(void)>, initAfterCallback=0x7f6f7c95f130 <<lambda(FILE*)>::_FUN(FILE *)>,
    initBeforeCallback=<optimized out>, fileName=0x1becf00 "/tmp/heaptrack_fifo14093") at /home/username/tmp/heaptrack/src/track/libheaptrack.cpp:260
 #7  heaptrack_init (outputFileName=0x1becf00 "/tmp/heaptrack_fifo14093", initBeforeCallback=<optimized out>, initAfterCallback=0x7f6f7c95f130 <<lambda(FILE*)>::_FUN(FILE *)>,
    stopCallback=0x7f6f7c95ef80 <<lambda()>::_FUN(void)>) at /home/username/tmp/heaptrack/src/track/libheaptrack.cpp:607
 #8  0x00007fffe684800f in ?? ()
 #9  0x0000000000000013 in ?? ()
 #10 0xcc00000000000002 in ?? ()
 #11 0x000000700000006e in ?? ()
 #12 0x0000000000000000 in ?? ()
(gdb) frame 5
 #5  0x00007f6f7c9634e4 in (anonymous namespace)::createFile (fileName=0x1becf00 "/tmp/heaptrack_fifo14093") at /home/username/tmp/heaptrack/src/track/libheaptrack.cpp:187
187	    __fsetlocking(out, FSETLOCKING_BYCALLER);
(gdb) print out
$1 = (_IO_FILE *) 0x0
(gdb) print fileName
$2 = 0x1becf00 "/tmp/heaptrack_fifo14093"
(gdb) frame 4
 #4  __GI___fsetlocking (fp=fp@entry=0x0, type=type@entry=2) at __fsetlocking.c:25
25	__fsetlocking.c: No such file or directory.
(gdb) print fp
$3 = (FILE *) 0x0
(gdb) up
 #5  0x00007f6f7c9634e4 in (anonymous namespace)::createFile (fileName=0x1becf00 "/tmp/heaptrack_fifo14093") at /home/username/tmp/heaptrack/src/track/libheaptrack.cpp:187
187	    __fsetlocking(out, FSETLOCKING_BYCALLER);
(gdb) list
182	    boost::replace_all(outputFileName, "$$", to_string(getpid()));
183
184	    auto out = fopen(outputFileName.c_str(), "w");
185	    debugLog<VerboseOutput>("will write to %s/%p\n", outputFileName.c_str(), out);
186	    // we do our own locking, this speeds up the writing significantly
187	    __fsetlocking(out, FSETLOCKING_BYCALLER);
188	    return out;
189	}
190
191	/**
(gdb) print outputFileName
$4 = "/tmp/heaptrack_fifo14093"
(gdb) q

```

To reproduce, and to visualize how this scenario is now handled:

$ LD_PRELOAD=lib/heaptrack/libheaptrack_preload.so \
  DUMP_HEAPTRACK_OUTPUT=/forbidden ls
ERROR: failed to open heaptrack output file /forbidden: Permission denied (13)
<normal ls output follows, no crash>

Original patch by Andrew Somerville, cleaned up by Milian.
  • Loading branch information
Andrew Somerville authored and milianw committed Nov 30, 2017
1 parent c6ef628 commit e66eb5b
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/track/libheaptrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,13 @@ FILE* createFile(const char* fileName)
auto out = fopen(outputFileName.c_str(), "w");
debugLog<VerboseOutput>("will write to %s/%p\n", outputFileName.c_str(), out);
// we do our own locking, this speeds up the writing significantly
__fsetlocking(out, FSETLOCKING_BYCALLER);
if (out) {
__fsetlocking(out, FSETLOCKING_BYCALLER);
} else {
fprintf(stderr, "ERROR: failed to open heaptrack output file %s: %s (%d)\n",
outputFileName.c_str(), strerror(errno), errno);
}

return out;
}

Expand Down Expand Up @@ -260,7 +266,6 @@ class HeapTrack
FILE* out = createFile(fileName);

if (!out) {
fprintf(stderr, "ERROR: Failed to open heaptrack output file: %s\n", fileName);
if (stopCallback) {
stopCallback();
}
Expand Down

0 comments on commit e66eb5b

Please sign in to comment.