Skip to content

Fix mremap wrapper for MREMAP_FIXED#1226

Merged
gc00 merged 2 commits intodmtcp:mainfrom
gc00:fix-mremap
Nov 15, 2025
Merged

Fix mremap wrapper for MREMAP_FIXED#1226
gc00 merged 2 commits intodmtcp:mainfrom
gc00:fix-mremap

Conversation

@gc00
Copy link
Copy Markdown
Contributor

@gc00 gc00 commented Nov 14, 2025

  • man page says: "If MREMAP_FIXED is specified, then MREMAP_MAYMOVE must also be specified. So, new_address is now used if flags | MREMAP_FIXED, not just flags == MREMAP_FIXED as before.
  • Add test/mremap.c, using MREMAP_FIXED

Summary by CodeRabbit

  • Bug Fixes

    • Corrected memory-remap flag handling so combinations including the fixed flag are processed correctly.
  • Tests

    • Added an automated test and a new test program to exercise memory remapping behavior.
  • Style

    • Rewrapped parameter lists and clarified/comment wording; formatting and comment edits only (no behavioral changes).

 * man page says: "If  MREMAP_FIXED  is specified, then MREMAP_MAYMOVE
   must also be specified.  So, new_address is used
   if "flags | MREMAP_FIXED", not just "flags == MREMAP_FIXED".
@gc00 gc00 requested a review from xuyao0127 November 14, 2025 06:29
@gc00 gc00 added the bug label Nov 14, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 14, 2025

Warning

Rate limit exceeded

@gc00 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 50 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between dbc3fee and dec266f.

📒 Files selected for processing (3)
  • src/mtcp/mtcp_restart.c (4 hunks)
  • test/autotest.py (1 hunks)
  • test/mremap.c (1 hunks)

Walkthrough

Restyles parameter wrapping and comment text in src/mtcp/mtcp_restart.c. Changes mremap handling in src/plugin/alloc/mmapwrappers.cpp to check MREMAP_FIXED as a bitwise flag and pass new_address when present. Adds a new mremap test test/mremap.c and registers it in test/autotest.py.

Changes

Cohort / File(s) Summary
Formatting & Comments
src/mtcp/mtcp_restart.c
Wrapped function parameter lists and call sites across lines; reflowed and corrected wording in comments (including typo fix "desgination" → "destination"). No functional changes.
mremap Flag Handling
src/plugin/alloc/mmapwrappers.cpp
Changed mremap check from flags == MREMAP_FIXED to flags & MREMAP_FIXED; when fixed flag present, read/pass new_address to _real_mremap.
Test Integration
test/autotest.py
Adds runTest("mremap", 1, ["./test/mremap"]) after the existing mmap1 test to execute the new test.
New Test Program
test/mremap.c
New C test that repeatedly mmap two regions, unmaps one, uses mremap with `MREMAP_MAYMOVE

Sequence Diagram(s)

sequenceDiagram
    participant App as Caller
    participant Wrap as mmapwrappers.cpp
    participant Real as _real_mremap

    rect rgb(250,250,250)
    note right of Wrap: Updated behavior — treat MREMAP_FIXED as a bitwise flag
    App->>Wrap: mremap(old_addr, old_len, new_len, flags[, new_addr])
    alt flags & MREMAP_FIXED
        Wrap->>Real: _real_mremap(..., new_addr)
    else
        Wrap->>Real: _real_mremap(...)
    end
    Real-->>Wrap: result (addr or MAP_FAILED)
    Wrap-->>App: return result
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review src/plugin/alloc/mmapwrappers.cpp for correct flag masking and safe handling of the optional new_address argument.
  • Verify test/mremap.c uses portable APIs and that assertions/cleanup are appropriate.
  • Quick skim of src/mtcp/mtcp_restart.c to ensure wrapping didn't alter semantics.

Suggested reviewers

  • xuyao0127
  • karya0

Poem

🐇
I hopped through lines both wrapped and neat,
Turned one flag check to a bitwise beat,
I made a test that leaps and sleeps,
Remaps by moon while memory keeps—
A tiny thump, a rabbit's feat.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main change: fixing the mremap wrapper to correctly handle MREMAP_FIXED flag, which aligns with the PR's primary objective of changing flag checking logic.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
test/mremap.c (1)

1-24: Test logic is sound; consider small robustness/portability tweaks

The loop correctly exercises mremap with MREMAP_MAYMOVE | MREMAP_FIXED and verifies that the mapping ends up at old_addr2, which should catch the wrapper bug.

Two non‑blocking suggestions to make the test more robust:

  • Use runtime page size instead of hard‑coding 4096. On systems with a different page size, munmap(old_addr2, 4096) can fail and leave old_addr2 still mapped, making the mremap precondition false. Using getpagesize() (already available via <unistd.h>) avoids this:

    int main() {
        size_t page_size = (size_t)getpagesize();
        void *old_addr1, *old_addr2, *new_addr;
        for (;;) {
            old_addr1 = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
                             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
            assert(old_addr1 != MAP_FAILED);
    
            old_addr2 = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
                             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
            assert(old_addr2 != MAP_FAILED);
    
            assert(munmap(old_addr2, page_size) == 0);
            new_addr = mremap(old_addr1, page_size, page_size,
                              MREMAP_MAYMOVE | MREMAP_FIXED, old_addr2);
            assert(new_addr == old_addr2);
            assert(munmap(old_addr2, page_size) == 0);
            sleep(1);
        }
    }
  • Add basic mmap/munmap error checks. As above, simple assert checks give clearer failures if the environment is misconfigured, rather than letting later calls behave unexpectedly.

If you want to keep the test minimal, even just switching to getpagesize() would address the main portability concern.

src/mtcp/mtcp_restart.c (1)

971-995: Comment update above mremap_move is accurate; optional spelling nit

The added note that MREMAP_MAYMOVE is required when using MREMAP_FIXED is correct and aligns with how mremap_move invokes mtcp_sys_mremap.

Minor nit (optional): in the comment, “desgination” could be corrected to “destination” for clarity:

// the memory was moved to the wrong destination.  Undo the move, and return -1.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88d7de4 and 9595d38.

📒 Files selected for processing (4)
  • src/mtcp/mtcp_restart.c (3 hunks)
  • src/plugin/alloc/mmapwrappers.cpp (1 hunks)
  • test/autotest.py (1 hunks)
  • test/mremap.c (1 hunks)
🧰 Additional context used
🪛 Clang (14.0.6)
test/mremap.c

[error] 2-2: 'assert.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (3)
test/autotest.py (1)

898-901: New mremap autotest wiring looks consistent

The added runTest("mremap", 1, ["./test/mremap"]) matches existing patterns (name, arg count, path) and being placed right after mmap1 makes sense logically. No issues from the harness side.

src/plugin/alloc/mmapwrappers.cpp (1)

56-71: Bitwise check for MREMAP_FIXED correctly fixes mixed‑flag usage

Switching to if (flags & MREMAP_FIXED) ensures the wrapper handles cases like MREMAP_MAYMOVE | MREMAP_FIXED and still pulls new_address from varargs, matching the kernel/glibc contract. The 4‑arg vs 5‑arg calls to _real_mremap remain consistent with the original ABI.

src/mtcp/mtcp_restart.c (1)

650-683: Refactoring/formatting around restore_vdso_vvar_work is harmless

Signature wrapping and the corresponding call for [vvar_vclock] are purely cosmetic; they don't alter arguments or control flow. The vdso/vvar handling logic remains intact.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
test/mremap.c (2)

11-15: Consider adding error handling for mmap and munmap calls.

While test programs may have relaxed error handling, adding checks for MAP_FAILED on mmap calls and return value checks on munmap would make test failures more explicit and easier to debug.

Example:

     old_addr1 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    assert(old_addr1 != MAP_FAILED);
     old_addr2 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    assert(old_addr2 != MAP_FAILED);
-    munmap(old_addr2, PAGE_SIZE);
+    assert(munmap(old_addr2, PAGE_SIZE) == 0);

20-21: Consider checking munmap return value for consistency.

Similar to Line 15, checking the return value of this munmap call would maintain consistency with error handling suggestions.

-    munmap(old_addr2, PAGE_SIZE);
+    assert(munmap(old_addr2, PAGE_SIZE) == 0);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9595d38 and 3d8e62d.

📒 Files selected for processing (3)
  • src/mtcp/mtcp_restart.c (3 hunks)
  • test/autotest.py (1 hunks)
  • test/mremap.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/autotest.py
🧰 Additional context used
🪛 Clang (14.0.6)
test/mremap.c

[error] 2-2: 'assert.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (5)
test/mremap.c (2)

2-2: Static analysis error is a false positive.

The Clang error about 'assert.h' not found is a false positive—this is a standard C header and will be available in the build environment.


17-19: LGTM! Core test logic correctly exercises MREMAP_FIXED.

The test correctly uses MREMAP_MAYMOVE | MREMAP_FIXED together, which aligns with the PR objective to fix the mremap wrapper to handle MREMAP_FIXED as a bitwise flag. The assertion will properly catch any mremap failures (which would return MAP_FAILED).

src/mtcp/mtcp_restart.c (3)

650-651: LGTM! Formatting improvement.

The parameter wrapping improves readability of the function signature.


681-682: LGTM! Consistent formatting.

The function call wrapping is consistent with the declaration formatting and improves readability.


972-974: LGTM! Documentation improvement aligns with PR objective.

The comment clarification that MREMAP_MAYMOVE is required when using MREMAP_FIXED directly supports the PR's objective to fix mremap wrapper handling of these flags.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d8e62d and dbc3fee.

📒 Files selected for processing (3)
  • src/mtcp/mtcp_restart.c (4 hunks)
  • test/autotest.py (1 hunks)
  • test/mremap.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/autotest.py
🧰 Additional context used
🪛 Clang (14.0.6)
test/mremap.c

[error] 2-2: 'assert.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
src/mtcp/mtcp_restart.c (4)

650-651: LGTM!

The function signature wrapping improves readability with no functional changes.


681-682: LGTM!

The function call wrapping maintains consistency with the signature formatting.


972-974: LGTM!

The comment clarification accurately documents the requirement that MREMAP_MAYMOVE must be specified when using MREMAP_FIXED, which aligns with the PR objectives.


992-992: LGTM!

The comment wording improvement enhances clarity.

test/mremap.c Outdated
Comment on lines +11 to +14
old_addr1 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
old_addr2 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error checking for mmap calls.

Both mmap calls should verify that the returned address is not MAP_FAILED before proceeding.

Apply this diff:

     old_addr1 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    assert(old_addr1 != MAP_FAILED);
     old_addr2 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    assert(old_addr2 != MAP_FAILED);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
old_addr1 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
old_addr2 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
old_addr1 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(old_addr1 != MAP_FAILED);
old_addr2 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(old_addr2 != MAP_FAILED);
🤖 Prompt for AI Agents
In test/mremap.c around lines 11 to 14, the two mmap() calls currently assume
success; add checks that the returned pointers are not MAP_FAILED and handle
errors if they are: after each mmap, test (old_addr1 == MAP_FAILED) and
(old_addr2 == MAP_FAILED), call perror("mmap") or fprintf(stderr, ...) to report
the failure and exit with a non-zero status (or return an error) so the test
does not continue with invalid addresses; ensure any already-mapped region is
munmap'ed before exiting if appropriate.

Copy link
Copy Markdown
Collaborator

@xuyao0127 xuyao0127 left a comment

Choose a reason for hiding this comment

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

LGTM

@gc00 gc00 merged commit f044085 into dmtcp:main Nov 15, 2025
2 checks passed
@gc00 gc00 deleted the fix-mremap branch November 15, 2025 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants