1/* Test program for libdwfl file descriptors 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 <unistd.h> 28#include <dwarf.h> 29#include "system.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 /* Get both the soft and hard limits first. The soft limit is what 105 will be enforced against the process. The hard limit is the max 106 that can be set for the soft limit. We don't want to lower it 107 because we might not be able to (under valgrind). */ 108 struct rlimit fd_limit; 109 if (getrlimit (RLIMIT_NOFILE, &fd_limit) < 0) 110 error (2, errno, "getrlimit"); 111 fd_limit.rlim_cur = 32; 112 if (setrlimit (RLIMIT_NOFILE, &fd_limit) < 0) 113 error (2, errno, "setrlimit"); 114 115 for (int i = 0; i < 5000; ++i) 116 { 117 Dwfl *dwfl = elfutils_open (getpid (), (Dwarf_Addr) (uintptr_t) &main); 118 elfutils_close (dwfl); 119 } 120 121 return 0; 122} 123#endif 124