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

--- Comment #4 from Tom de Vries <vries at gcc dot gnu.org> ---
Comment on attachment 45048
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45048
Proposed patch

>@@ -1476,6 +1483,15 @@ build_address_map (struct backtrace_stat
>          backtrace_alloc (state, sizeof *u, error_callback, data));
>       if (u == NULL)
>       goto fail;
>+
>+      pu = ((struct unit **)
>+          backtrace_vector_grow (state, sizeof (struct unit *),
>+                                 error_callback, data, &units));
>+      if (pu == NULL)

This introduces another memory leak, this is missing here:
...
        {
        backtrace_free (state, u, sizeof *u, error_callback, data);
...

>+      goto fail;

...
        }
...

[ Btw, note that if we move the u and pu allocations to before read_abbrevs, we
can read the abbrevs directly into u->abbrevs, and can get rid of the
"free_abbrevs (&abbrevs)" at the end. Perhaps that's worth a separate patch. ]

>@@ -1502,23 +1518,37 @@ build_address_map (struct backtrace_stat
>                               u, addrs))
>       {
>         free_abbrevs (state, &u->abbrevs, error_callback, data);
>-        backtrace_free (state, u, sizeof *u, error_callback, data);
>         goto fail;
>       }
> 
>       if (unit_buf.reported_underflow)
>       {
>         free_abbrevs (state, &u->abbrevs, error_callback, data);
>-        backtrace_free (state, u, sizeof *u, error_callback, data);
>         goto fail;
>       }
>     }
>   if (info.reported_underflow)
>     goto fail;
> 

>  fail:
>+  if (units_count > 0)
>+    {
>+      pu = (struct unit **) units.base;
>+      for (i = 0; i < units_count; i++)
>+      backtrace_free (state, *pu, sizeof **pu, error_callback, data);

"*pu" is constant in the loop, and should be "pu[i]".

Also, now that we loop over all units, the simplest solution is to free the
abbrevs in the same loop, and get rid of the two free_abbrevs above and the
free_unit_addrs_vector below.

This also fixes a memory leak of abbrevs referenced from a unit that has no
corresponding struct unit_addr. [ OTOH, that's a memory leak in the fail case,
but corresponds to unused memory in the success case, so we might wanna fix
that as well, by keeping track of the number of struct unit_addr found, and
freeing the struct unit at the end of the 'while (info.left > 0)' loop when
it's 0. Perhaps that's worth a seperate patch. ]

>+      units.alc += units.size;
>+      units.size = 0;
>+      backtrace_vector_release (state, &units, error_callback, data);
>+    }
>   free_abbrevs (state, &abbrevs, error_callback, data);
>   free_unit_addrs_vector (state, addrs, error_callback, data);

The call to free_unit_addrs_vector does not free the actual vector, I think
that's another memory leak.

>   return 0;

Reply via email to