Skip to content

Comments

fix: copy_file skip files larger than 1GB (Fixes #4039)#4051

Closed
IamHuskar wants to merge 4 commits intorr-debugger:masterfrom
IamHuskar:fix_dotnet_doublemapping
Closed

fix: copy_file skip files larger than 1GB (Fixes #4039)#4051
IamHuskar wants to merge 4 commits intorr-debugger:masterfrom
IamHuskar:fix_dotnet_doublemapping

Conversation

@IamHuskar
Copy link

@IamHuskar IamHuskar commented Feb 7, 2026

The original PR at #4048 . should use rebase instead of merge.

@IamHuskar
Copy link
Author

Why is the MAP_SHARED check placed after copy_file?

!(km.flags() & MAP_SHARED)) {
Can we change the order of these if conditions?
If the km region is MAP_SHARED, src.setTrace will be executed, but at that point, the file copying has already been completed.

// the size of km is not equal to the file size obtained through the fstat
struct stat src_stat;
ScopedFd src_fd(file_name.c_str(), O_RDONLY);
if (src_fd.is_open() && (fstat(src_fd.get(), &src_stat) == 0)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can use the stat that's a parameter to TraceWriter::write_mapped_region().

Copy link
Author

Choose a reason for hiding this comment

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

You can use the stat that's a parameter to TraceWriter::write_mapped_region().

I searched through all the code and found that some function calls to write_mapped_region pass xxx.fake_stat() as an argument, meaning the stat here might be the result of fake_stat. Can we still directly use stat here?

typedef void (*simple_func_t)(void);

#ifdef __x86_64__
static const unsigned char x86_ret_instruction = 0xC3; // ret
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think you actually need to map and execute code. All you need to do is construct a really large totally empty mapping, map it PROT_EXEC, and hopefully that will cause the test to time out if this bug is not fixed properly.

@IamHuskar
Copy link
Author

It seems that after running scripts/reformat.sh, the code formatting changes dramatically. I wonder if it's due to the version of clang-format. How should I format my code?
@rocallahan

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.

copy_file(km.fsname(), file_name, &backing_file_name) &&
!(km.flags() & MAP_SHARED)) {
(!(km.flags() & MAP_SHARED) &&
(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.

@@ -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.

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.

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

int ret=-1;
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.

int fd = memfd_create("double_mapper_test", MFD_CLOEXEC);
do
{
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.

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.

#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.

@IamHuskar IamHuskar force-pushed the fix_dotnet_doublemapping branch from 6d491ec to 2517dff Compare February 14, 2026 07:31
@IamHuskar IamHuskar closed this Feb 14, 2026
@IamHuskar IamHuskar deleted the fix_dotnet_doublemapping branch February 14, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants