[PATCH v4] elf: parse /proc/self/maps as the last resort to find the gap for tst-link-map-contiguous-ldso

Florian Weimer fweimer@redhat.com
Mon Feb 2 10:13:08 GMT 2026


* Xi Ruoyao:

> The initialization process of libc.so calls mmap() several times and the
> kernel may lay the maps into the gap.  If all pages in the gap are
> occupied, the test would not be able to find the gap with mmap() and the
> test would fail.
>
> The failure reproduces most frequently on LoongArch because with the
> commonly used page size (16 KiB) the gap only contains 4 pages and the
> probability they are all occupied is not near to zero.
>
> With the changes in the patch, a test run may output:
>
>     info: ld.so link map is not contiguous
>     info: object "/dev/zero" found at 0x7ffff1fe0000 - 0x7ffff1fe4000
>     info: anonymous mapping found at 0x7ffff1fe4000 - 0x7ffff1fec000
>
> Also take the chance to fix a mistake in the "object found at" message
> which has puzzled me during the initial debug session.
>
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>

Just a few style nits.

> +/* Slow path in case we cannot find a gap with mmap (when the runtime has
> +   mapped all the pages in the gap for some reason).  */
> +static bool
> +find_gap_with_proc_self_map (const struct link_map *l)
> +{
> +  int pagesize = getpagesize ();
> +
> +  support_need_proc ("Reads /proc/self/maps to find gap in ld.so mapping");
> +
> +  /* Parse /proc/self/maps and find all the mappings in the ld.so range
> +     but not from ld.so.  */
> +  FILE *f = xfopen ("/proc/self/maps", "r");
> +  char *line = NULL, *path_ldso = NULL;
> +  size_t len;
> +  bool found = false;
> +  while (xgetline (&line, &len, f))
> +    {
> +      uintptr_t from, to;
> +      char *path = NULL;
> +      int r = sscanf (line, "%" SCNxPTR "-%" SCNxPTR "%*s%*s%*s%*s%ms",
> +                      &from, &to, &path);
> +
> +      TEST_VERIFY (r == 2 || r == 3);
> +      TEST_COMPARE (from % pagesize, 0);
> +      TEST_COMPARE (to % pagesize, 0);
> +
> +      if (!path_ldso && l->l_map_start == from)

We generally prefer writing path_ldso != NULL.

> +        {
> +          TEST_COMPARE (r, 3);
> +          path_ldso = path;
> +          continue;
> +        }
> +
> +      if (from > l->l_map_start && to < l->l_map_end
> +          && (r == 2 || (path_ldso && strcmp (path, path_ldso))))

Here as well.

> +        {
> +          if (r == 2)
> +            printf ("info: anonymous mapping found at 0x%" SCNxPTR " - 0x%"
> +                    SCNxPTR "\n", from, to);
> +          else
> +            printf ("info: object \"%s\" found at 0x%" SCNxPTR " - 0x%"
> +                    SCNxPTR "\n", path, from, to);

Please use PRIxPTR here.

> +
> +          found = true;
> +        }
> +
> +      free (path);
> +    }
> +
> +  free (path_ldso);
> +  return found;
> +}

Could close f here and free line.

Thanks,
Florian



More information about the Libc-alpha mailing list