Hello,

I'm working on porting packages having PATH_MAX issues and ruby1.9.1 is
one of them. PATH_MAX is not defined for GNU/Hurd. The code analysis
below shows that it would be possible to use dynamic allocation of the
buffer binary_filename using malloc and free.

However, Samuel Thibault, a large contributor to GNU/Hurd and a Debiab
Developer, advised me to ask here is it is possible or if a
fixed-length buffer should be used? Especially if it is safe to call
rb_dump_backtrace_with_lines from a *Unix* signal handler.

So if dynamic allocation is not possible, can you in the next release
provide a conditional definition of PATH_MAX?

#ifndef PATH_MAX
#define PATH_MAX 4096
#endif

> > Below is a patch attempt to solve the PATH_MAX issue on the latest
> > ruby1.9.1.

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;

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 the following might/might not work:

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

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

allocates a new value to binary_filename:
       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);


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.

    free(binary_filename)

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*)(malloc(len) + 1);

A new pointer for binary_filename is created

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

}

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

Thanks!