[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

A quiz: Re: Second patch attempt for PATH_MAX fix in ruby1.9.1- 1.9.3~rc1-3



On Fri, 2011-10-14 at 11:17 +0200, Pino Toscano wrote:
> Hi,
> 
> Alle giovedì 13 ottobre 2011, Svante Signell ha scritto:
> > Below is a patch attempt to solve the PATH_MAX issue on the latest
> > ruby1.9.1.
> 
> I don't think this is correct: various functions in addr2line.c seem to 
> assume the buffer is always the same, and they call themselves 
> recursively (e.g. rb_dump_backtrace_with_lines (sets binary_filename) -> 
> fill_lines -> follow_debuglink (sets binary_filename) -> fill_lines -> 
> ...). With your patch, it would also cause the binary_filename pointer 
> to be stale over runs.

Code analysis follows below:

binary_filename is a global variable:
/* Avoid consuming stack as this module may be used from signal handler
*/
static char *binary_filename = NULL;

It wouldn't work with alloca, maybe with malloc!

Call order:
rb_dump_backtrace_with_lines()->fill_lines()->
follow_debuglink()->parse_debug_line()->parse_debug_line_cu()

rb_dump_backtrace_with_lines() copies binary_filename content to path.
follow_debuglink() creates new content of binary_filename.

binary_filename needed in parse_debug_line() and parse_debug_line_cu()

I think it might/might not work:

rb_dump_backtrace_with_lines():
===============================

creates comtent in path:
        if (!get_path_from_symbol(syms[i], &path, &len)) {
            continue;
        }

allocates a new value to binary_filename:
        binary_filename = (char *)(alloca(len) + 1);
or      binary_filename = (char *)(malloc(len) + 1);

A new pointer for binary_filename is created.

        strncpy(binary_filename, path, len);
	binary_filename[len] = '\0';

calls fill_lines():
        fill_lines(num_traces, trace, syms, 1, &lines[i], lines);

alloca():Here memory for binary_filename is freed: Bad!
Not the case if malloc is used! 

fill_lines():
=============
opens a file:
   fd = open(binary_filename, O_RDONLY);

makes a comparison:
         if (get_path_from_symbol(syms[i], &path, &len) &&
                !strncmp(path, binary_filename, len)) {
            lines[i].line = -1;
        }

calls follow_debuglink():
        if (gnu_debuglink_shdr && check_debuglink) {
            follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
                             num_traces, traces, syms,
                             current_line, lines);

calls parse_debug_line():
   parse_debug_line(num_traces, traces,
                     file + debug_line_shdr->sh_offset,
                     debug_line_shdr->sh_size,
                     lines);

follow_debuglink()
==================
static const char global_debug_dir[] = "/usr/lib/debug";

Here the previously malloced binary_filename is needed!

    subdir = (char *)alloca(strlen(binary_filename) + 1);
    strcpy(subdir, binary_filename);

Here the content of binary_filename is copied to subdir. 
Binary_filename can be disposed.

Question: free(binary_filename); is needed here in order not to allocate
a new pointer without disposing the old one??

The binary_filename is concatenated to:
global_debug_dir+subdir+debuglink

    len = strlen(global_debug_dir) + strlen(subdir) + strlen(debuglink);
    binary_filename = (char*)(alloca(len) + 1);
or  binary_filename = (char*)(malloc(len) + 1);

A new pointer for binary_filename is created: Is realloc usable?

    strcpy(binary_filename, global_debug_dir);
    strncat(binary_filename, subdir, strlen(subdir));
    strncat(binary_filename, debuglink, strlen(debuglink));
    binary_filename[len] = '\0';

}
alloca():Here memory for binary_filename is freed: Bad!
Not the case if malloc is used! 

parse_debug_line():
===================
Here the previously malloced binary_filename is needed!

    while (debug_line < debug_line_end) {
        parse_debug_line_cu(num_traces, traces, &debug_line, lines);

prints using binary_filename

parse_debug_line_cu():
======================
Here the previously malloced binary_filename is needed!

prints using binary_filename



Reply to: