1/* Test program for libdwfl file decriptors leakage. 2 Copyright (C) 2007, 2008 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 elfutils is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18#include <config.h> 19#include <assert.h> 20#include <inttypes.h> 21#include <stdio.h> 22#include <stdio_ext.h> 23#include <locale.h> 24#include <dirent.h> 25#include <stdlib.h> 26#include <errno.h> 27#include <error.h> 28#include <unistd.h> 29#include <dwarf.h> 30 31#ifndef __linux__ 32int 33main (void) 34{ 35 return 77; /* dwfl_linux_proc_report is linux specific. */ 36} 37#else 38 39#include <sys/resource.h> 40#include ELFUTILS_HEADER(dwfl) 41 42 43static Dwfl * 44elfutils_open (pid_t pid, Dwarf_Addr address) 45{ 46 static char *debuginfo_path; 47 static const Dwfl_Callbacks proc_callbacks = 48 { 49 .find_debuginfo = dwfl_standard_find_debuginfo, 50 .debuginfo_path = &debuginfo_path, 51 52 .find_elf = dwfl_linux_proc_find_elf, 53 }; 54 Dwfl *dwfl = dwfl_begin (&proc_callbacks); 55 if (dwfl == NULL) 56 error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); 57 58 int result = dwfl_linux_proc_report (dwfl, pid); 59 if (result < 0) 60 error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1)); 61 else if (result > 0) 62 error (2, result, "dwfl_linux_proc_report"); 63 64 if (dwfl_report_end (dwfl, NULL, NULL) != 0) 65 error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1)); 66 67 Dwarf_Addr bias; 68 Dwarf *dbg = dwfl_addrdwarf (dwfl, address, &bias); 69 if (dbg != NULL) 70 { 71 Elf *elf = dwarf_getelf (dbg); 72 if (elf == NULL) 73 error (2, 0, "dwarf_getelf: %s", dwarf_errmsg (-1)); 74 } 75 else 76 { 77 Dwfl_Module *module = dwfl_addrmodule (dwfl, address); 78 if (module == NULL) 79 error (2, 0, "dwfl_addrmodule: no module available for 0x%" PRIx64 "", 80 address); 81 Elf *elf = dwfl_module_getelf (module, &bias); 82 if (elf == NULL) 83 error (2, 0, "dwfl_module_getelf: %s", dwfl_errmsg (-1)); 84 } 85 86 return dwfl; 87} 88 89static void 90elfutils_close (Dwfl *dwfl) 91{ 92 dwfl_end (dwfl); 93} 94 95int 96main (void) 97{ 98 /* We use no threads here which can interfere with handling a stream. */ 99 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); 100 101 /* Set locale. */ 102 (void) setlocale (LC_ALL, ""); 103 104 struct rlimit fd_limit = { .rlim_cur = 32, .rlim_max = 32 }; 105 if (setrlimit (RLIMIT_NOFILE, &fd_limit) < 0) 106 error (2, errno, "setrlimit"); 107 108 for (int i = 0; i < 5000; ++i) 109 { 110 Dwfl *dwfl = elfutils_open (getpid (), (Dwarf_Addr) (uintptr_t) &main); 111 elfutils_close (dwfl); 112 } 113 114 return 0; 115} 116#endif 117