https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85840

            Bug ID: 85840
           Summary: Memory leak in write.c
           Product: gcc
           Version: 7.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jjcogliati-r1 at yahoo dot com
  Target Milestone: ---

This bug comes from trying to find a memory leak in my own program.

gfortran --version
GNU Fortran (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The line in my code was:

print '(A16,I7,6E25.16E3)',"start line print",i,a,b,c,d,e,f

where a,b,c,d,e,f are complicated real kinds.

The valgrind trace was:

==23064== 142,120 bytes in 440 blocks are definitely lost in loss record 39 of
49
==23064==    at 0x4C2CB6B: malloc (vg_replace_malloc.c:299)
==23064==    by 0x4E53454: _gfortrani_xmalloc (memory.c:42)
==23064==    by 0x4FD637A: write_float_0 (write.c:1593)
==23064==    by 0x4FCD98C: formatted_transfer_scalar_write (transfer.c:2041)
==23064==    by 0x4FCDF9C: formatted_transfer (transfer.c:2279)


Looking at write.c, we have:
  /* String buffer to hold final result.  */
  result = select_string (dtp, f, str_buf, &res_len, kind); //line 1593

  buffer = select_buffer (dtp, f, precision, buf_stack, &buf_size, kind);

  get_float_string (dtp, f, source , kind, 0, buffer,
                           precision, buf_size, result, &res_len);
  write_float_string (dtp, result, res_len);

  if (buf_size > BUF_STACK_SZ)
    free (buffer);
  if (res_len > BUF_STACK_SZ)
    free (result);

Notice that we assign to the value of res_len from select_string AND from
get_float_string, and get_float_string can assign to the length in functions
called from it such as in build_float_string

So I think what is happening is res_len is getting assigned a number that is
smaller than BUF_STACK_SZ, and then result is not getting freed.

I haven't come up with a small test case yet, but I certainly can if needed.

Reply via email to