Hi Mark,

I tried to use the program you showed me (attached below) which gets a
list of source files from DWARF by calling dwarf_getsrcfiles from
libdw. The dwarf_getsrcfiles function calls the dwarf_getsrclines
function, which uses stack (alloca) to store intermediate data when
reading/processing .debug_lines. Using stack this way doesn't scale, the
program receives SIGSEGV for stack overflow when trying to process real
debug files.

$ ./dwarfsrcfiles /usr/lib/debug/usr/bin/enfuse.debug
Segmentation fault (core dumped)

The reason is that ./dwarfsrcfiles needs approx. 15 MB on stack to
process enfuse.debug (37MB, from enblend-debuginfo Fedora 14 package).

$ ulimit -a | grep stack
stack size              (kbytes, -s) 8192

When I increase the stack size, it works as expected:
$ valgrind --main-stacksize=16000000 ./dwarfsrcfiles 
/usr/lib/debug/usr/bin/enfuse.debug

One could increase the stack size limit permanently on a machine, but it
doesn't seem to be the right solution: there are even bigger debuginfo
files in Fedora today, and the code size (=> dwarf size) is growing over
years, while the default stack size limit not so much.

I guess that most of the stack is used for storing lines in the NEW_LINE
macro in dwarf_getsrclines. You might want to consider using the heap
there.

Kind regards,
Karel Klic

// dwarfsrcfiles.c - Get source files associated with the dwarf in a elf file.
// gcc -Wall -g -O2 -lelf -ldw -o dwarfsrcfiles dwarfsrcfiles.c 
//
// Copyright (C) 2011, Mark Wielaard <[email protected]>
//
// This file is free software.  You can redistribute it and/or modify
// it under the terms of the GNU General Public License (GPL); either
// version 2, or (at your option) any later version.

#include <argp.h>
#include <error.h>
#include <stdio.h>

#include <dwarf.h>
#include <elfutils/libdw.h>
#include <elfutils/libdwfl.h>

static int
process_cu (Dwarf_Die *cu_die)
{
  Dwarf_Attribute attr;
  const char *name;
  const char *dir = NULL;
  
  Dwarf_Files *files;
  size_t n;
  int i;
  
  if (dwarf_tag (cu_die) != DW_TAG_compile_unit)
    {
      error (0, 0, "DIE isn't a compile unit");
      return -1;
    }
  
  if (dwarf_attr (cu_die, DW_AT_name, &attr) == NULL)
    {
      error (0, 0, "CU doesn't have a DW_AT_name");
      return -1;
    }
  
  name = dwarf_formstring (&attr);
  if (name == NULL)
    {
      error (0, 0, "Couldn't get DW_AT_name as string, %s",
             dwarf_errmsg (-1));
      return -1;
    }
  
  if (dwarf_attr (cu_die, DW_AT_comp_dir, &attr) != NULL)
    {
      dir = dwarf_formstring (&attr);
      if (dir == NULL)
        {
          error (0, 0, "Couldn't get DW_AT_comp_die as string, %s",
                 dwarf_errmsg (-1));
          return -1;
        }
    }
  
  if (dir == NULL)
    printf ("%s\n", name);
  else
    printf ("%s/%s\n", dir, name);
  
  if (dwarf_getsrcfiles (cu_die, &files, &n) != 0)
    {
      error (0, 0, "Couldn't get CU file table, %s",
             dwarf_errmsg (-1));
      return -1;
    }
  
  for (i = 1; i < n; i++)
    {
      const char *file = dwarf_filesrc (files, i, NULL, NULL);
      if (dir != NULL && file[0] != '/')
        printf ("\t%s/%s\n", dir, file);
      else
        printf ("\t%s\n", file);
    }
  
  return 0;
}

int
main (int argc, char **argv)
{
  char* args[3];
  int res = 0;
  Dwfl *dwfl;
  Dwarf_Addr bias;
  
  if (argc != 2)
    error (-1, 0, "Usage %s <file>", argv[0]);
  
  // Pretend "dwarfsrcfiles -e <file>" was given, so we can use standard
  // dwfl argp parser to open the file for us and get our Dwfl. Useful
  // in case argument is an ET_REL file (like kernel modules). libdwfl
  // will fix up relocations for us.
  args[0] = argv[0];
  args[1] = "-e";
  args[2] = argv[1];
  
  argp_parse (dwfl_standard_argp (), 3, args, 0, NULL, &dwfl);
  
  Dwarf_Die *cu = NULL;
  while ((cu = dwfl_nextcu (dwfl, cu, &bias)) != NULL)
    res |= process_cu (cu);
  
  dwfl_end (dwfl);

  return res;
}
_______________________________________________
elfutils-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/elfutils-devel

Reply via email to