Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop when trying to allocate large object (v8.2.8) #691

Open
ysbaddaden opened this issue Dec 16, 2024 · 5 comments
Open

Infinite loop when trying to allocate large object (v8.2.8) #691

ysbaddaden opened this issue Dec 16, 2024 · 5 comments

Comments

@ysbaddaden
Copy link

ysbaddaden commented Dec 16, 2024

I regularly reproduce an issue with v8.2: when trying to allocate a large object, the following loop repeats infinitely:

bdwgc/malloc.c

Lines 66 to 69 in e7f6ef3

while (0 == h && GC_collect_or_expand(n_blocks, flags != 0, retry)) {
h = GC_allochblk(lb, k, flags);
retry = TRUE;
}

strace repeatedly prints the following:

mmap(0x791a67412000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a66200000
mmap(0x791a66a02000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a65800000
mmap(0x791a66002000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a64e00000
mmap(0x791a65602000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a64400000
mmap(0x791a64c02000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a63a00000
mmap(0x791a64202000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a63000000
mmap(0x791a63802000, 8396800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a62600000
mmap(0x791a62e02000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x791a62e02000

Here's a backtrace from a gdb session:

#0  0x0000637d4c08a7f0 in GC_allochblk_nth (sz=sz@entry=4194320, kind=kind@entry=0, flags=flags@entry=0, n=n@entry=60, may_split=may_split@entry=1) at allchblk.c:772
#1  0x0000637d4c08b3e2 in GC_allochblk (sz=sz@entry=4194320, kind=kind@entry=0, flags=flags@entry=0) at allchblk.c:726
#2  0x0000637d4c08f4ae in GC_alloc_large (lb=<optimized out>, lb@entry=4194320, k=k@entry=0, flags=flags@entry=0) at malloc.c:67
#3  0x0000637d4c08fab8 in GC_generic_malloc (lb=4194304, k=0) at malloc.c:268
#4  0x0000637d4c08fcc1 in GC_malloc_kind_global (lb=4194304, k=0) at malloc.c:339
#5  0x0000637d4c0903cb in GC_generic_or_special_malloc (knd=<optimized out>, lb=4194304) at mallocx.c:62
#6  GC_realloc (p=0x7967cac25000, lb=4194304) at mallocx.c:162
#7  0x0000637d4b2cda5a in realloc () at /home/julien/work/crystal-lang/crystal/src/gc/boehm.cr:198
#8  0x0000637d4b2cda06 in realloc () at /home/julien/work/crystal-lang/crystal/src/gc.cr:102

Trying to step in gdb:

  • GC_collect_or_expand never tries to collect and keeps expanding the memory;
  • GC_expand_hp_inner(blocks_to_get) always returns TRUE;
  • GC_allochblk and GC_allochblk_nth keep returning 0 (note that split_limit and start_list are both set to 60).
GC_collect_or_expand (needed_blocks=needed_blocks@entry=1025, ignore_off_page=ignore_off_page@entry=0, retry=1) at alloc.c:1671
GC_expand_hp_inner (n=n@entry=2050) at alloc.c:1558

Environment information:

Linux 6.9 / glibc 2.35 / Pop OS (Ubuntu 22.04)

BDWGC 8.2.8 compiled as a static lib and otherwise using configuration defaults (mmap, munmap, disclaim, parallel mark, etc). So far I haven't been able to reproduce with the current master branch (but no guarantee).

It started happening in a branch of the crystal language related to multi-threading. It doesn't change anything to GC or memory allocation in general or even threads: I reproduce while running the std test suite in a single thread, and it happens with no other threads (except for the waiting GC threads). I just reproduced on the master branch of Crystal.

@ivmai
Copy link
Owner

ivmai commented Dec 16, 2024

Although I don't think it is fixed, please recheck it on release-8_2 branch. If reproducible, then I think it exists on master as well (but not possible to reproduce on master as the alloc logic has been changed significantly).

@ysbaddaden
Copy link
Author

I still haven't been able to reproduce using the master branch (at commit 25c2b6a) after running the crystal stdlib specs in a loop for hours.

I'm trying the release-8_2 branch now.

@ysbaddaden
Copy link
Author

I reproduced twice with the release-8_2 branch.

I still can't reproduce with the master branch. Maybe the alloc changes make it harder to trigger? I'll keep trying.

@ivmai
Copy link
Owner

ivmai commented Dec 18, 2024

I still can't reproduce with the master branch. Maybe the alloc changes make it harder to trigger? I'll keep trying.

No need to reproduce on master, release-8_2 branch is OK. It is better to spend efforts to figure out how to fix it. (Maybe will look at it this week, but I am not sure.)

@ivmai
Copy link
Owner

ivmai commented Dec 18, 2024

Looks like the scenario that breaks the heuristic. (master branch has a bit different heuristic and thus you can't reproduce it with the given scenario)
Let me think what how to fix the heuristic.
Maybe @hboehm could advise the fix?
https://github.com/ivmai/bdwgc/blob/v8.2.8/allchblk.c#L725

@ivmai ivmai changed the title Infinite loop when trying to allocate large object (v8.2) Infinite loop when trying to allocate large object (v8.2.8) Dec 18, 2024
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

No branches or pull requests

2 participants