Changeset 14e2ab9
- Timestamp:
- 05/28/15 12:50:12 (10 years ago)
- Branches:
- master
- Children:
- 97550d2
- Parents:
- a736d81
- git-author:
- Hal Finkel <hfinkel@…> (05/28/15 12:50:12)
- git-committer:
- Hal Finkel <hfinkel@…> (05/28/15 12:50:12)
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r0a0ef57 r14e2ab9 2 2 CFLAGS = -O3 -g 3 3 4 UNW_HOME = ${HOME}/install/libunwind 5 CPPFLAGS = -I$(UNW_HOME)/include 6 LDFLAGS = -L$(UNW_HOME)/lib64 -Wl,-rpath,$(UNW_HOME)/lib64 -lunwind -lpthread -ldl 4 CPPFLAGS = 5 LDFLAGS = -lpthread -ldl 7 6 8 7 all: memlog.so memlog.a -
memlog.c
ra736d81 r14e2ab9 20 20 #include <pthread.h> 21 21 22 #define UNW_LOCAL_ONLY23 #include <libunwind.h>24 25 22 #include <dlfcn.h> 26 23 … … 57 54 } 58 55 59 static void print_context( unw_context_t *context) {56 static void print_context(void *caller) { 60 57 struct rusage usage; 61 58 if (getrusage(RUSAGE_SELF, &usage)) { … … 67 64 usage.ru_utime.tv_usec, usage.ru_maxrss, syscall(SYS_gettid)); 68 65 69 int r;70 unw_cursor_t cursor;71 if ((r = unw_init_local(&cursor, context))) {72 fprintf(stderr, "unw_init_local failed: %s [%d]\n",73 unw_strerror(r), r);74 return;75 }76 77 66 void *pcs[1024]; 78 67 int num_pcs = backtrace(pcs, 1024); 68 69 int found_caller = 0; 79 70 for (int pci = 0; pci < num_pcs; ++pci) { 80 unw_word_t pc = (unw_word_t) pcs[pci]; 81 #if 0 82 while ((r = unw_step(&cursor)) > 0) { 83 unw_word_t pc; 84 if ((r = unw_get_reg(&cursor, UNW_REG_IP, &pc))) { 85 fprintf(stderr, "unw_get_reg UNW_REG_IP failed: %s [%d]\n", 86 unw_strerror(r), r); 87 return; 88 } 89 #endif 71 intptr_t pc = (intptr_t) pcs[pci]; 90 72 91 73 if (!pc) 92 74 break; 93 75 94 unw_word_t off, relpc; 76 if (!found_caller) { 77 if (pc != (intptr_t) caller) 78 continue; 79 80 found_caller = 1; 81 } 82 83 intptr_t off, relpc; 95 84 const char *proc_name; 96 85 const char *file_name; … … 98 87 if (dladdr((void *) pc, &dlinfo) && dlinfo.dli_fname && 99 88 *dlinfo.dli_fname) { 100 unw_word_t saddr = (unw_word_t) dlinfo.dli_saddr;89 intptr_t saddr = (intptr_t) dlinfo.dli_saddr; 101 90 if (saddr) { 102 91 #if defined(__powerpc64__) && !defined(__powerpc64le__) 103 92 // On PPC64 ELFv1, the symbol address points to the function descriptor, not 104 93 // the actual starting address. 105 saddr = *( unw_word_t*) saddr;94 saddr = *(intptr_t*) saddr; 106 95 #endif 107 96 108 97 off = pc - saddr; 109 relpc = pc - (( unw_word_t) dlinfo.dli_fbase);98 relpc = pc - ((intptr_t) dlinfo.dli_fbase); 110 99 } else { 111 100 off = 0; … … 127 116 fprintf(log_file, "\t%s (%s+0x%x) [0x%lx (0x%lx)]", file_name, proc_name, (int) off, 128 117 (long) pc, (long) relpc); 129 130 #if 0131 unw_word_t off;132 char proc_name[PATH_MAX];133 if (unw_get_proc_name(&cursor, proc_name, PATH_MAX, &off)) {134 off = 0;135 strcpy(proc_name, "?");136 }137 138 unw_proc_info_t pip;139 if ((r = unw_get_proc_info(&cursor, &pip))) {140 // unw_get_proc_info is not supported on some platforms (ppc and ppc64,141 // for example), so we need to try harder...142 if (r == -UNW_EINVAL) {143 unw_word_t pc;144 if ((r = unw_get_reg(&cursor, UNW_REG_IP, &pc))) {145 fprintf(stderr, "unw_get_reg UNW_REG_IP failed: %s [%d]\n",146 unw_strerror(r), r);147 return;148 }149 150 if ((r = unw_get_proc_info_by_ip(unw_local_addr_space, pc, &pip, NULL))) {151 if (r == -UNW_ENOINFO)152 break; // the cursor is now invalid; must break here.153 154 fprintf(stderr, "unw_get_proc_info_by_ip failed: %s [%d]\n",155 unw_strerror(r), r);156 return;157 }158 } else {159 if (r == -UNW_ENOINFO)160 break; // the cursor is now invalid; must break here.161 162 fprintf(stderr, "unw_get_proc_info failed: %s [%d]\n",163 unw_strerror(r), r);164 return;165 }166 }167 168 const char *file_name;169 Dl_info dlinfo;170 if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&171 *dlinfo.dli_fname)172 file_name = dlinfo.dli_fname;173 else174 file_name = "?";175 176 fprintf(log_file, "\t%s (%s+0x%x) [%p]", file_name, proc_name, (int) off,177 (void *) (pip.start_ip + off));178 #endif179 118 } 180 181 if (r < 0 && r != -UNW_ENOINFO) 182 fprintf(stderr, "unw_step failed: %s [%d]\n", 183 unw_strerror(r), r); 184 } 185 186 static void record_malloc(size_t size, void *ptr, unw_context_t *uc) { 119 } 120 121 static void record_malloc(size_t size, void *ptr, void *caller) { 187 122 if (!log_file) 188 123 return; … … 192 127 193 128 fprintf(log_file, "M: %zd %p", size, ptr); 194 print_context( uc);129 print_context(caller); 195 130 fprintf(log_file, "\n"); 196 131 … … 199 134 } 200 135 201 static void record_free(void *ptr, unw_context_t *uc) {136 static void record_free(void *ptr, void *caller) { 202 137 if (!log_file) 203 138 return; … … 207 142 208 143 fprintf(log_file, "F: %p", ptr); 209 print_context( uc);144 print_context(caller); 210 145 fprintf(log_file, "\n"); 211 146 … … 230 165 void *ptr = __libc_malloc(size); 231 166 232 unw_context_t uc; 233 if (!unw_getcontext(&uc)) 234 record_malloc(size, ptr, &uc); 167 void *caller = __builtin_return_address(0); 168 record_malloc(size, ptr, caller); 235 169 236 170 in_malloc = 0; … … 246 180 void *nptr = __libc_realloc(ptr, size); 247 181 248 unw_context_t uc; 249 if (!unw_getcontext(&uc)) { 250 record_free(ptr, &uc); 251 record_malloc(size, nptr, &uc); 252 } 182 void *caller = __builtin_return_address(0); 183 if (ptr) 184 record_free(ptr, caller); 185 record_malloc(size, nptr, caller); 253 186 254 187 in_malloc = 0; … … 265 198 void *ptr = __libc_calloc(nmemb, size); 266 199 267 unw_context_t uc; 268 if (!unw_getcontext(&uc)) 269 record_malloc(nmemb*size, ptr, &uc); 200 void *caller = __builtin_return_address(0); 201 record_malloc(nmemb*size, ptr, caller); 270 202 271 203 in_malloc = 0; … … 282 214 void *ptr = __libc_memalign(boundary, size); 283 215 284 unw_context_t uc; 285 if (!unw_getcontext(&uc)) 286 record_malloc(size, ptr, &uc); 216 void *caller = __builtin_return_address(0); 217 record_malloc(size, ptr, caller); 287 218 288 219 in_malloc = 0; … … 292 223 293 224 void free(void *ptr) { 294 if (in_malloc )225 if (in_malloc || !ptr) 295 226 return __libc_free(ptr); 296 227 297 228 in_malloc = 1; 298 229 299 unw_context_t uc; 300 if (!unw_getcontext(&uc)) 301 record_free(ptr, &uc); 230 void *caller = __builtin_return_address(0); 231 record_free(ptr, caller); 302 232 303 233 __libc_free(ptr);
Note: See TracChangeset
for help on using the changeset viewer.