Skip to content

Segmentation Fault on "out of memory" in backtrace_free_locked #149

@piesarmin

Description

@piesarmin

The following stacktrace snippet shows the problem:

#0  backtrace_free_locked (state=state@entry=0x7f2da76b2000, addr=addr@entry=0x0, size=size@entry=784) at mmap.c:104
#1  0x0000000000e88533 in backtrace_free_locked (size=784, addr=0x0, state=0x7f2da76b2000) at mmap.c:226
#2  backtrace_free (state=state@entry=0x7f2da76b2000, addr=0x0, size=784, error_callback=error_callback@entry=0xc704d0 <boost::stacktrace::detail::libbacktrace_error_callback(void*, char const*, int)>, data=data@entry=0x7f2e8b8765c0)
    at mmap.c:233
#3  0x0000000000e8bef3 in free_line_header (data=0x7f2e8b8765c0, error_callback=0xc704d0 <boost::stacktrace::detail::libbacktrace_error_callback(void*, char const*, int)>, hdr=0x7f2e8b876310, state=0x7f2da76b2000) at dwarf.c:2669
#4  read_line_info (lines_count=<synthetic pointer>, lines=<synthetic pointer>, hdr=0x7f2e8b876310, u=<optimized out>, data=0x7f2da7676e30,
    error_callback=0xc704d0 <boost::stacktrace::detail::libbacktrace_error_callback(void*, char const*, int)>, ddata=0x7f2e8b8765c0, state=0x7f2d8f8e41e0) at dwarf.c:3340

The parameter addr is NULL. That leads to a segmentation fault in mmap.c:104:

103  p = (struct backtrace_freelist_struct *) addr;
104  p->next = state->freelist;

Due to this segmentation fault, the actual problem, namely the 'out of memory' error, is obscured. With the following patch in the function free_line_header in dwarf.c, especially with the check "hdr->filenames != NULL", we were able to prevent the crash at this point:

static void
free_line_header (struct backtrace_state *state, struct line_header *hdr,
		  backtrace_error_callback error_callback, void *data)
{
  if ((hdr->dirs_count != 0) && (hdr->dirs != NULL))
    {
      backtrace_free(state,
                     hdr->dirs,
                     hdr->dirs_count * sizeof(const char *),
                     error_callback,
                     data);
    }
  if ((hdr->filenames_count != 0) && (hdr->filenames != NULL))
    {
      backtrace_free(state,
                     hdr->filenames,
                     hdr->filenames_count * sizeof(char *),
                     error_callback,
                     data);
    }
}

Please check our patch. It might also make more sense to perform the check directly in backtrace_free_locked? Thank you for your effort.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions