Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1294)

Side by Side Diff: sanitizer_common/sanitizer_symbolizer_linux.cc

Issue 6448179: [Sanitizer] wrapper for external symbolizer program (Closed) Base URL: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/
Patch Set: z Created 12 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sanitizer_common/sanitizer_symbolizer.cc ('k') | sanitizer_common/sanitizer_symbolizer_llvm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===-- sanitizer_symbolizer_linux.cc -------------------------------------===// 1 //===-- sanitizer_symbolizer_linux.cc -------------------------------------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file is shared between AddressSanitizer and ThreadSanitizer 10 // This file is shared between AddressSanitizer and ThreadSanitizer
11 // run-time libraries. 11 // run-time libraries.
12 // Linux-specific implementation of symbolizer parts. 12 // Linux-specific implementation of symbolizer parts.
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 #ifdef __linux__ 14 #ifdef __linux__
15 #include "sanitizer_common.h" 15 #include "sanitizer_common.h"
16 #include "sanitizer_internal_defs.h" 16 #include "sanitizer_internal_defs.h"
17 #include "sanitizer_libc.h"
17 #include "sanitizer_placement_new.h" 18 #include "sanitizer_placement_new.h"
18 #include "sanitizer_symbolizer.h" 19 #include "sanitizer_symbolizer.h"
19 20
20 #include <elf.h> 21 #include <elf.h>
22 #include <errno.h>
21 #include <link.h> 23 #include <link.h>
24 #include <poll.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
22 #include <unistd.h> 27 #include <unistd.h>
23 28
24 namespace __sanitizer { 29 namespace __sanitizer {
25 30
26 typedef ElfW(Ehdr) Elf_Ehdr; 31 bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
27 typedef ElfW(Shdr) Elf_Shdr; 32 int *input_fd, int *output_fd) {
28 typedef ElfW(Phdr) Elf_Phdr; 33 int *infd = NULL;
29 34 int *outfd = NULL;
30 bool FindDWARFSection(uptr object_file_addr, const char *section_name, 35 // The client program may close its stdin and/or stdout and/or stderr
31 DWARFSection *section) { 36 // thus allowing socketpair to reuse file descriptors 0, 1 or 2.
32 Elf_Ehdr *exe = (Elf_Ehdr*)object_file_addr; 37 // In this case the communication between the forked processes may be
33 Elf_Shdr *sections = (Elf_Shdr*)(object_file_addr + exe->e_shoff); 38 // broken if either the parent or the child tries to close or duplicate
34 uptr section_names = object_file_addr + 39 // these descriptors. The loop below produces two pairs of file
35 sections[exe->e_shstrndx].sh_offset; 40 // descriptors, each greater than 2 (stderr).
36 for (int i = 0; i < exe->e_shnum; i++) { 41 int sock_pair[5][2];
37 Elf_Shdr *current_section = &sections[i]; 42 for (int i = 0; i < 5; i++) {
38 const char *current_name = (const char*)section_names + 43 if (pipe(sock_pair[i]) == -1) {
39 current_section->sh_name; 44 for (int j = 0; j < i; j++) {
40 if (IsFullNameOfDWARFSection(current_name, section_name)) { 45 internal_close(sock_pair[j][0]);
41 section->data = (const char*)object_file_addr + 46 internal_close(sock_pair[j][1]);
42 current_section->sh_offset; 47 }
43 section->size = current_section->sh_size; 48 Report("WARNING: Can't create a socket pair to start "
44 return true; 49 "external symbolizer (errno: %d)\n", errno);
50 return false;
51 } else if (sock_pair[i][0] > 2 && sock_pair[i][1] > 2) {
52 if (infd == NULL) {
53 infd = sock_pair[i];
54 } else {
55 outfd = sock_pair[i];
56 for (int j = 0; j < i; j++) {
57 if (sock_pair[j] == infd) continue;
58 internal_close(sock_pair[j][0]);
59 internal_close(sock_pair[j][1]);
60 }
61 break;
62 }
45 } 63 }
46 } 64 }
47 return false; 65 CHECK(infd);
66 CHECK(outfd);
67
68 int pid = fork();
69 if (pid == -1) {
70 // Fork() failed.
71 internal_close(infd[0]);
72 internal_close(infd[1]);
73 internal_close(outfd[0]);
74 internal_close(outfd[1]);
75 Report("WARNING: failed to fork external symbolizer "
76 " (errno: %d)\n", errno);
77 return false;
78 } else if (pid == 0) {
79 // Child subprocess.
80 internal_close(STDOUT_FILENO);
81 internal_close(STDIN_FILENO);
82 internal_dup2(outfd[0], STDIN_FILENO);
83 internal_dup2(infd[1], STDOUT_FILENO);
84 internal_close(outfd[0]);
85 internal_close(outfd[1]);
86 internal_close(infd[0]);
87 internal_close(infd[1]);
88 for (int fd = getdtablesize(); fd > 2; fd--)
89 internal_close(fd);
90 execl(path_to_symbolizer, path_to_symbolizer, (char*)0);
91 Exit(1);
92 }
93
94 // Continue execution in parent process.
95 internal_close(outfd[0]);
96 internal_close(infd[1]);
97 *input_fd = infd[0];
98 *output_fd = outfd[1];
99 return true;
48 } 100 }
49 101
50 #ifdef ANDROID 102 #ifdef ANDROID
51 uptr GetListOfModules(ModuleDIContext *modules, uptr max_modules) { 103 uptr GetListOfModules(LoadedModule *modules, uptr max_modules) {
52 UNIMPLEMENTED(); 104 UNIMPLEMENTED();
53 } 105 }
54 #else // ANDROID 106 #else // ANDROID
107 typedef ElfW(Phdr) Elf_Phdr;
108
55 struct DlIteratePhdrData { 109 struct DlIteratePhdrData {
56 ModuleDIContext *modules; 110 LoadedModule *modules;
57 uptr current_n; 111 uptr current_n;
58 uptr max_n; 112 uptr max_n;
59 }; 113 };
60 114
61 static const uptr kMaxPathLength = 512; 115 static const uptr kMaxPathLength = 512;
62 116
63 static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { 117 static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
64 DlIteratePhdrData *data = (DlIteratePhdrData*)arg; 118 DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
65 if (data->current_n == data->max_n) 119 if (data->current_n == data->max_n)
66 return 0; 120 return 0;
67 char *module_name = 0; 121 char *module_name = 0;
68 if (data->current_n == 0) { 122 if (data->current_n == 0) {
69 // First module is the binary itself. 123 // First module is the binary itself.
70 module_name = (char*)InternalAlloc(kMaxPathLength); 124 module_name = (char*)InternalAlloc(kMaxPathLength);
71 uptr module_name_len = readlink("/proc/self/exe", 125 uptr module_name_len = readlink("/proc/self/exe",
72 module_name, kMaxPathLength); 126 module_name, kMaxPathLength);
73 CHECK_NE(module_name_len, (uptr)-1); 127 CHECK_NE(module_name_len, (uptr)-1);
74 CHECK_LT(module_name_len, kMaxPathLength); 128 CHECK_LT(module_name_len, kMaxPathLength);
75 module_name[module_name_len] = '\0'; 129 module_name[module_name_len] = '\0';
76 } else if (info->dlpi_name) { 130 } else if (info->dlpi_name) {
77 module_name = internal_strdup(info->dlpi_name); 131 module_name = internal_strdup(info->dlpi_name);
78 } 132 }
79 if (module_name == 0 || module_name[0] == '\0') 133 if (module_name == 0 || module_name[0] == '\0')
80 return 0; 134 return 0;
81 void *mem = &data->modules[data->current_n]; 135 void *mem = &data->modules[data->current_n];
82 ModuleDIContext *cur_module = new(mem) ModuleDIContext(module_name, 136 LoadedModule *cur_module = new(mem) LoadedModule(module_name,
83 info->dlpi_addr); 137 info->dlpi_addr);
84 data->current_n++; 138 data->current_n++;
85 for (int i = 0; i < info->dlpi_phnum; i++) { 139 for (int i = 0; i < info->dlpi_phnum; i++) {
86 const Elf_Phdr *phdr = &info->dlpi_phdr[i]; 140 const Elf_Phdr *phdr = &info->dlpi_phdr[i];
87 if (phdr->p_type == PT_LOAD) { 141 if (phdr->p_type == PT_LOAD) {
88 uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; 142 uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;
89 uptr cur_end = cur_beg + phdr->p_memsz; 143 uptr cur_end = cur_beg + phdr->p_memsz;
90 cur_module->addAddressRange(cur_beg, cur_end); 144 cur_module->addAddressRange(cur_beg, cur_end);
91 } 145 }
92 } 146 }
93 InternalFree(module_name); 147 InternalFree(module_name);
94 return 0; 148 return 0;
95 } 149 }
96 150
97 uptr GetListOfModules(ModuleDIContext *modules, uptr max_modules) { 151 uptr GetListOfModules(LoadedModule *modules, uptr max_modules) {
98 CHECK(modules); 152 CHECK(modules);
99 DlIteratePhdrData data = {modules, 0, max_modules}; 153 DlIteratePhdrData data = {modules, 0, max_modules};
100 dl_iterate_phdr(dl_iterate_phdr_cb, &data); 154 dl_iterate_phdr(dl_iterate_phdr_cb, &data);
101 return data.current_n; 155 return data.current_n;
102 } 156 }
103 #endif // ANDROID 157 #endif // ANDROID
104 158
105 } // namespace __sanitizer 159 } // namespace __sanitizer
106 160
107 #endif // __linux__ 161 #endif // __linux__
OLDNEW
« no previous file with comments | « sanitizer_common/sanitizer_symbolizer.cc ('k') | sanitizer_common/sanitizer_symbolizer_llvm.cc » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b