United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7017193 Small memory leak in get_stack_bounds // os::create_stack_guard_pages
JDK-7017193 : Small memory leak in get_stack_bounds // os::create_stack_guard_pages

Details
Type:
Bug
Submit Date:
2011-02-04
Status:
Closed
Updated Date:
2013-02-26
Project Name:
JDK
Resolved Date:
2011-04-25
Component:
hotspot
OS:
generic
Sub-Component:
runtime
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
hs20
Fixed Versions:
hs21 (b09)

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
Valgrind reports small memory leak in get_stack_bounds // os::create_stack_guard_pages.

The reason there is leak is that getline() may return -1 and still allocate memory in str:

    ssize_t len = getline(&str, &dummy, f);
    if (len == -1) {
      fclose(f);
      return false;

                                    

Comments
EVALUATION

In a product build the leak only occurs once - for the initial thread. For debug builds it occurs for all threads.

The docs for getline do not make it clear whether it checks for any available input before allocating the buffer, so we should be conservative and always free on each exit path.

Also note that this code is inefficient in that it requires getline to create a new buffer on each call. The buffer could be reused (and resized by getline if needed) on each iteration of the loop and only freed on exit from the method. See suggested fix.
                                     
2011-02-14
SUGGESTED FIX

static bool
get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
{
  FILE *f = fopen("/proc/self/maps", "r");
  if (f == NULL)
    return false;
+ char *str = NULL;
  while (!feof(f)) {
    size_t dummy;
-   char *str = NULL;
    ssize_t len = getline(&str, &dummy, f);
    if (len == -1) {
+     free(str);
      fclose(f);
      return false;
    }

    if (len > 0 && str[len-1] == '\n') {
      str[len-1] = 0;
      len--;
    }

    static const char *stack_str = "[stack]";
    if (len > (ssize_t)strlen(stack_str)
       && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
      if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
        uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
        if (sp >= *bottom && sp <= *top) {
          free(str);
          fclose(f);
          return true;
        }
      }
    }
-    free(str);
  }
+ free(str);
  fclose(f);
  return false;
}
                                     
2011-02-14
I did some experiments with readline and find it's behaviour inconsistent 
across platforms and glibc versions. So decided to getrid of it.
                                     
2011-02-15
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/rev/677234770800
                                     
2011-03-31



Hardware and Software, Engineered to Work Together