Skip to content

builder: fix infinite loop in find_module_path for projects at a Windows drive root - #27473

Merged
JalonSolov merged 5 commits into
vlang:masterfrom
quaesitor-scientiam:fix/windows-drive-root-module-lookup-hang
Jun 23, 2026
Merged

builder: fix infinite loop in find_module_path for projects at a Windows drive root#27473
JalonSolov merged 5 commits into
vlang:masterfrom
quaesitor-scientiam:fix/windows-drive-root-module-lookup-hang

Conversation

@quaesitor-scientiam

Copy link
Copy Markdown
Contributor

What

Fixes an infinite loop (100% CPU, no output, never completes) when building a V
project located directly under a drive root on Windows (e.g. S:\proj).
This also makes make / makev.bat hang at the
Compiling "./v_stage.exe" with "./v_win_bootstrap.exe" step for drive-root
checkouts.

Fixes #27472

Root cause

In find_module_path() (vlib/v/builder/builder.v), the loop that anchors an
importer to the outermost enclosing v.mod never terminated for a drive-root
project:

  • os.dir("S:\proj") returns the bare drive "S:".
  • inside get_by_folder("S:"), os.real_path("S:") resolves a bare drive
    letter to that drive's current directory ("S:\proj"), i.e. back into the
    project.

So importer_vmod_folder never moved up, while the loop's guard compared the
unresolved "S:" against the full "S:\proj" and never broke. At a nested path
(S:\repo\proj) the parent has no v.mod, so the loop exited normally — which
is why moving the checkout one level deeper avoided the hang.

Fix

Only climb when the resolved parent v.mod is a strict ancestor of the
current folder. This terminates both:

  • the fixpoint case (project directly under a drive root), and
  • a multi-step oscillation (a project nested under such a drive-root project,
    where the bare-drive real_path jump can bounce between an outer and inner
    v.mod).

The vendored-modules/ anchoring this loop was originally added for is
preserved, since a real outer v.mod is always a strict ancestor.

Testing

  • Before: building cmd/v from a drive-root checkout never completes;
    from a nested path it takes ~6s.
  • After: building cmd/v from a drive-root checkout completes normally, and the
    resulting compiler self-rebuilds at the drive root in ~7s.
  • v -silent vlib/v/builder/base_url_test.v (covers find_module_path) passes.

Note

make / makev.bat bootstrap their first stage from the pre-generated
vc/v_win.c, so the bootstrap step will keep hanging at a drive-root checkout
until vlang/vc is regenerated with this fix.

🧙 Built with WOZCODE

…ows drive root

When a V project is located directly under a drive root (e.g. `S:\proj`),
`find_module_path`'s "anchor to the outermost enclosing v.mod" loop never
terminated, so building the project (including `make`/`makev.bat`) hung
forever at 100% CPU.

`os.dir("S:\proj")` returns the bare drive `"S:"`, and inside
`get_by_folder` `os.real_path("S:")` resolves a bare drive letter to that
drive's *current directory* (back into the project), so the walked folder
never moved up while the loop's guard compared the unresolved `"S:"` against
the full path and never broke.

Only climb when the resolved parent v.mod is a strict ancestor of the current
folder. This handles both the fixpoint case (project at a drive root) and the
multi-step oscillation case (a project nested under such a drive-root project).

Fixes vlang#27472

Co-Authored-By: WOZCODE <contact@withwoz.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.

gechandesu added a commit to gechandesu/netio that referenced this pull request Jun 16, 2026
@quaesitor-scientiam

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 8141a0de94

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@JalonSolov

Copy link
Copy Markdown
Collaborator

Bouncing to pick up changes in master...

@JalonSolov JalonSolov closed this Jun 18, 2026
@JalonSolov JalonSolov reopened this Jun 18, 2026
@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8141a0de94

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vlib/v/builder/builder.v Outdated
quaesitor-scientiam and others added 2 commits June 19, 2026 15:59
On Windows, os.dir('C:\project') returns 'C:' (bare drive letter with no
trailing slash). os.dir('C:') returns '.' and os.dir('.') returns '.' —
a fixed point that the existing '/' stop condition in traverse never
catches, causing the upward vmod search to burn 255 iterations instead
of stopping cleanly. Any caller of get_by_folder/get_by_file was exposed
(checker, util, vdoc, vpm), not just builder.

Fix traverse (vmod.v) to break as soon as os.dir stops making progress
(next == cfolder). This is the correct general stop condition and
subsumes the Windows drive-root, Unix root, and '.' cases in one check.

Add is_strict_ancestor in builder.find_module_path as a belt-and-
suspenders guard: stop climbing the outermost-vmod chain whenever the
cache returns a candidate that is not a strict path ancestor of the
current folder. Implemented by delegating to the existing
comparable_real_path + path_is_at_or_inside helpers already in the file.

Co-Authored-By: WOZCODE <contact@withwoz.com>
@quaesitor-scientiam

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 1bc1dfd9dd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@JalonSolov

Copy link
Copy Markdown
Collaborator

Merge master in for a final run of the CI with all the latest changes. Some, if not all, of the failures have been fixed in master... and whatever is left probably isn't related to your changes... but it's hard to tell with so many lines of output...

Co-Authored-By: WOZCODE <contact@withwoz.com>
@quaesitor-scientiam

Copy link
Copy Markdown
Contributor Author

CI failures are unrelated to this PR

@JalonSolov

Copy link
Copy Markdown
Collaborator

Agreed

@JalonSolov
JalonSolov merged commit ddc9c99 into vlang:master Jun 23, 2026
81 of 93 checks passed
@quaesitor-scientiam
quaesitor-scientiam deleted the fix/windows-drive-root-module-lookup-hang branch June 28, 2026 03:20
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.

Windows: building a V project located directly under a drive root hangs forever (infinite loop in find_module_path)

3 participants