Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,7 @@ set(BASIC_TESTS
memfd_create_efault
memfd_create_shared
memfd_create_shared_huge
memfd_create_dotnet_huge_mapping
mincore
mknod
mlock
Expand Down
7 changes: 5 additions & 2 deletions src/TraceStream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -995,10 +995,13 @@ TraceWriter::RecordInTrace TraceWriter::write_mapped_region(
// debuggers can't find the file, but the Linux loader doesn't create
// shared mappings so situations where a shared-mapped executable contains
// usable debug info should be very rare at best...
// copy files when the mapping is PROT_EXEC, unless the file is too big
// sometimes km.size() does not equal the file size from fstat().
string backing_file_name;
if ((km.prot() & PROT_EXEC) &&
copy_file(km.fsname(), file_name, &backing_file_name) &&
!(km.flags() & MAP_SHARED)) {
(!(km.flags() & MAP_SHARED) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first ( (and the matching )) is unnecessary.

(stat.st_size <= 1024 * 1024 * 1024/*1GB*/) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ( and the matching ) are also unnecessary.

copy_file(km.fsname(), file_name, &backing_file_name))) {
src.initFile().setBackingFileName(str_to_data(backing_file_name));
} else {
src.setTrace();
Expand Down
61 changes: 61 additions & 0 deletions src/test/memfd_create_dotnet_huge_mapping.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "util.h"
#include <time.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure this #include is not necessary.

#define memfd_create(...) syscall(__NR_memfd_create, __VA_ARGS__)
/*
https://github.com/dotnet/runtime/blob/23aeecc9f91a9ae0a211702dbd849c90cdd81d36/src/coreclr/minipal/Unix/doublemapping.cpp#L85
#ifdef TARGET_64BIT
static const off_t MaxDoubleMappedSize = 2048ULL*1024*1024*1024;
#else
static const off_t MaxDoubleMappedSize = UINT_MAX;
#endif
To prevent bugs that could result in writing a 2TB file, a 20GB limit is used instead.
*/
#define _1GB (1024 * 1024 * 1024ULL)
unsigned long long MaxDoubleMappedSize = 20 * _1GB;
#define PAGE_SIZE_4K 4096
int test_ftruncate_huge_mapping(void)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can return void.

{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please manually format this the way we normally do, with { on the same line as the function declaration.

int ret=-1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use spaces the way we normally do.

int fd = memfd_create("double_mapper_test", MFD_CLOEXEC);
do
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here and below.

if (fd == -1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use test_assert(fd >= 0) instead.

{
atomic_puts("memfd_create failed");
break;
}
if (ftruncate(fd, MaxDoubleMappedSize) == -1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

{
atomic_puts("ftruncate failed");
break;
}
void* executable_addr = mmap(NULL, PAGE_SIZE_4K, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
if (executable_addr == MAP_FAILED)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

{
atomic_puts("mmap for executable mapping failed");
break;
}
munmap(executable_addr, PAGE_SIZE_4K);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't really need to munmap, it's fine to leak it in a test.

ret = 0;
} while (0);
if(fd!=-1){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And use spaces here like the rest of our code.

close(fd);
}
return ret;
}

int main(void)
{
#if defined(__i386__)
atomic_puts("Skipping test on 32 bit");
#else
struct timespec start, end;
test_assert(-1 != clock_gettime(CLOCK_MONOTONIC, &start));
test_ftruncate_huge_mapping();
test_assert(-1 != clock_gettime(CLOCK_MONOTONIC, &end));
//check timeout
test_assert((end.tv_sec - start.tv_sec) <= 2);
#endif
atomic_puts("EXIT-SUCCESS");
return 0;
}