[GCOV] Close file mapping handle on Windows, so flushed gcda files can be removed while the process is in execution
llvm-svn: 346300
This commit is contained in:
parent
a8ffa52498
commit
ed4bb266c8
|
@ -29,6 +29,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
#include "WindowsMMap.h"
|
#include "WindowsMMap.h"
|
||||||
#else
|
#else
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -86,6 +88,9 @@ static uint64_t cur_buffer_size = 0;
|
||||||
static uint64_t cur_pos = 0;
|
static uint64_t cur_pos = 0;
|
||||||
static uint64_t file_size = 0;
|
static uint64_t file_size = 0;
|
||||||
static int new_file = 0;
|
static int new_file = 0;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static HANDLE mmap_handle = NULL;
|
||||||
|
#endif
|
||||||
static int fd = -1;
|
static int fd = -1;
|
||||||
|
|
||||||
typedef void (*fn_ptr)();
|
typedef void (*fn_ptr)();
|
||||||
|
@ -255,6 +260,28 @@ static int map_file() {
|
||||||
if (file_size == 0)
|
if (file_size == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
HANDLE mmap_fd;
|
||||||
|
if (fd == -1)
|
||||||
|
mmap_fd = INVALID_HANDLE_VALUE;
|
||||||
|
else
|
||||||
|
mmap_fd = (HANDLE)_get_osfhandle(fd);
|
||||||
|
|
||||||
|
mmap_handle = CreateFileMapping(mmap_fd, NULL, PAGE_READWRITE, DWORD_HI(file_size), DWORD_LO(file_size), NULL);
|
||||||
|
if (mmap_handle == NULL) {
|
||||||
|
fprintf(stderr, "profiling: %s: cannot create file mapping: %d\n", filename,
|
||||||
|
GetLastError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_buffer = MapViewOfFile(mmap_handle, FILE_MAP_WRITE, 0, 0, file_size);
|
||||||
|
if (write_buffer == NULL) {
|
||||||
|
fprintf(stderr, "profiling: %s: cannot map: %d\n", filename,
|
||||||
|
GetLastError());
|
||||||
|
CloseHandle(mmap_handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
write_buffer = mmap(0, file_size, PROT_READ | PROT_WRITE,
|
write_buffer = mmap(0, file_size, PROT_READ | PROT_WRITE,
|
||||||
MAP_FILE | MAP_SHARED, fd, 0);
|
MAP_FILE | MAP_SHARED, fd, 0);
|
||||||
if (write_buffer == (void *)-1) {
|
if (write_buffer == (void *)-1) {
|
||||||
|
@ -263,10 +290,30 @@ static int map_file() {
|
||||||
strerror(errnum));
|
strerror(errnum));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmap_file() {
|
static void unmap_file() {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if (!FlushViewOfFile(write_buffer, file_size)) {
|
||||||
|
fprintf(stderr, "profiling: %s: cannot flush mapped view: %d\n", filename,
|
||||||
|
GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UnmapViewOfFile(write_buffer)) {
|
||||||
|
fprintf(stderr, "profiling: %s: cannot unmap mapped view: %d\n", filename,
|
||||||
|
GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CloseHandle(mmap_handle)) {
|
||||||
|
fprintf(stderr, "profiling: %s: cannot close file mapping handle: %d\n", filename,
|
||||||
|
GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
mmap_handle = NULL;
|
||||||
|
#else
|
||||||
if (msync(write_buffer, file_size, MS_SYNC) == -1) {
|
if (msync(write_buffer, file_size, MS_SYNC) == -1) {
|
||||||
int errnum = errno;
|
int errnum = errno;
|
||||||
fprintf(stderr, "profiling: %s: cannot msync: %s\n", filename,
|
fprintf(stderr, "profiling: %s: cannot msync: %s\n", filename,
|
||||||
|
@ -277,6 +324,8 @@ static void unmap_file() {
|
||||||
* is written and we don't care.
|
* is written and we don't care.
|
||||||
*/
|
*/
|
||||||
(void)munmap(write_buffer, file_size);
|
(void)munmap(write_buffer, file_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
write_buffer = NULL;
|
write_buffer = NULL;
|
||||||
file_size = 0;
|
file_size = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,6 @@
|
||||||
|
|
||||||
#include "InstrProfiling.h"
|
#include "InstrProfiling.h"
|
||||||
|
|
||||||
#ifdef __USE_FILE_OFFSET64
|
|
||||||
# define DWORD_HI(x) (x >> 32)
|
|
||||||
# define DWORD_LO(x) ((x) & 0xffffffff)
|
|
||||||
#else
|
|
||||||
# define DWORD_HI(x) (0)
|
|
||||||
# define DWORD_LO(x) (x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
COMPILER_RT_VISIBILITY
|
COMPILER_RT_VISIBILITY
|
||||||
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
|
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,14 @@
|
||||||
#define LOCK_NB 4 /* don't block when locking */
|
#define LOCK_NB 4 /* don't block when locking */
|
||||||
#define LOCK_UN 8 /* unlock */
|
#define LOCK_UN 8 /* unlock */
|
||||||
|
|
||||||
|
#ifdef __USE_FILE_OFFSET64
|
||||||
|
# define DWORD_HI(x) (x >> 32)
|
||||||
|
# define DWORD_LO(x) ((x) & 0xffffffff)
|
||||||
|
#else
|
||||||
|
# define DWORD_HI(x) (0)
|
||||||
|
# define DWORD_LO(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
void *mmap(void *start, size_t length, int prot, int flags, int fd,
|
void *mmap(void *start, size_t length, int prot, int flags, int fd,
|
||||||
off_t offset);
|
off_t offset);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
int main(void) {
|
||||||
|
__gcov_flush();
|
||||||
|
|
||||||
|
if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__gcov_flush();
|
||||||
|
__gcov_flush();
|
||||||
|
|
||||||
|
if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-gcov-__gcov_flush-multiple.c
|
||||||
|
// CHECK-NEXT: -: 0:Graph:instrprof-gcov-__gcov_flush-multiple.gcno
|
||||||
|
// CHECK-NEXT: -: 0:Data:instrprof-gcov-__gcov_flush-multiple.gcda
|
||||||
|
// CHECK-NEXT: -: 0:Runs:1
|
||||||
|
// CHECK-NEXT: -: 0:Programs:1
|
||||||
|
// CHECK-NEXT: #####: 1:int main(void) {
|
||||||
|
// CHECK-NEXT: #####: 2: __gcov_flush();
|
||||||
|
// CHECK-NEXT: -: 3:
|
||||||
|
// CHECK-NEXT: #####: 4: if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) {
|
||||||
|
// CHECK-NEXT: #####: 5: return 1;
|
||||||
|
// CHECK-NEXT: -: 6: }
|
||||||
|
// CHECK-NEXT: -: 7:
|
||||||
|
// CHECK-NEXT: #####: 8: __gcov_flush();
|
||||||
|
// CHECK-NEXT: #####: 9: __gcov_flush();
|
||||||
|
// CHECK-NEXT: -: 10:
|
||||||
|
// CHECK-NEXT: #####: 11: if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) {
|
||||||
|
// CHECK-NEXT: #####: 12: return 1;
|
||||||
|
// CHECK-NEXT: -: 13: }
|
||||||
|
// CHECK-NEXT: -: 14:
|
||||||
|
// CHECK-NEXT: 1: 15: return 0;
|
||||||
|
// CHECK-NEXT: 1: 16:}
|
|
@ -0,0 +1,10 @@
|
||||||
|
RUN: mkdir -p %t.d
|
||||||
|
RUN: cd %t.d
|
||||||
|
|
||||||
|
RUN: %clang --coverage -o %t %S/Inputs/instrprof-gcov-__gcov_flush-multiple.c
|
||||||
|
RUN: test -f instrprof-gcov-__gcov_flush-multiple.gcno
|
||||||
|
|
||||||
|
RUN: rm -f instrprof-gcov-__gcov_flush-multiple.gcda
|
||||||
|
RUN: %run %t
|
||||||
|
RUN: llvm-cov gcov instrprof-gcov-__gcov_flush-multiple.gcda
|
||||||
|
RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-__gcov_flush-multiple.c.gcov %S/Inputs/instrprof-gcov-__gcov_flush-multiple.c.gcov
|
Loading…
Reference in New Issue