1 /* 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <stdarg.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <limits.h> 31 32 #include <sys/stat.h> 33 34 #ifdef _MSC_VER 35 #include <direct.h> 36 #include <io.h> 37 #include <process.h> 38 #else 39 #include <unistd.h> 40 #endif 41 42 #include "constants.h" 43 #include "defines.h" 44 #include "bytes.h" 45 #include "utils.h" 46 47 #include "unpack.h" 48 49 void* must_malloc(size_t size) { 50 size_t msize = size; 51 #ifdef USE_MTRACE 52 if (msize >= 0 && msize < sizeof(int)) 53 msize = sizeof(int); // see 0xbaadf00d below 54 #endif 55 void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize); 56 if (ptr != null) { 57 memset(ptr, 0, size); 58 } else { 59 unpack_abort(ERROR_ENOMEM); 60 } 61 mtrace('m', ptr, size); 62 return ptr; 63 } 64 65 void mkdirs(int oklen, char* path) { 66 67 if (strlen(path) <= (size_t)oklen) return; 68 char dir[PATH_MAX]; 69 70 strcpy(dir, path); 71 char* slash = strrchr(dir, '/'); 72 if (slash == 0) return; 73 *slash = 0; 74 mkdirs(oklen, dir); 75 MKDIR(dir); 76 } 77 78 79 #ifndef PRODUCT 80 void breakpoint() { } // hook for debugger 81 int assert_failed(const char* p) { 82 char message[1<<12]; 83 sprintf(message, "@assert failed: %s\n", p); 84 fprintf(stdout, "%s", 1+message); 85 breakpoint(); 86 unpack_abort(message); 87 return 0; 88 } 89 #endif 90 91 void unpack_abort(const char* msg, unpacker* u) { 92 if (msg == null) msg = "corrupt pack file or internal error"; 93 if (u == null) 94 u = unpacker::current(); 95 if (u == null) { 96 fprintf(stderr, "Error: unpacker: %s\n", msg); 97 ::abort(); 98 return; 99 } 100 u->abort(msg); 101 } 102 103 bool unpack_aborting(unpacker* u) { 104 if (u == null) 105 u = unpacker::current(); 106 if (u == null) { 107 fprintf(stderr, "Error: unpacker: no current instance\n"); 108 ::abort(); 109 return true; 110 } 111 return u->aborting(); 112 } 113 114 #ifdef USE_MTRACE 115 // Use this occasionally for detecting storage leaks in unpack. 116 void mtrace(char c, void* ptr, size_t size) { 117 if (c == 'f') *(int*)ptr = 0xbaadf00d; 118 static FILE* mtfp; 119 if (mtfp == (FILE*)-1) return; 120 if (mtfp == null) { 121 if (getenv("USE_MTRACE") == null) { 122 mtfp = (FILE*)-1; 123 return; 124 } 125 char fname[1024]; 126 sprintf(fname, "mtr%d.txt", getpid()); 127 mtfp = fopen(fname, "w"); 128 if (mtfp == null) 129 mtfp = stdout; 130 } 131 fprintf(mtfp, "%c %p %p\n", c, ptr, (void*)size); 132 } 133 134 /* # Script for processing memory traces. 135 # It should report only a limited number (2) of "suspended" blocks, 136 # even if a large number of archive segments are processed. 137 # It should report no "leaked" blocks at all. 138 nawk < mtr*.txt ' 139 function checkleaks(what) { 140 nd = 0 141 for (ptr in allocated) { 142 if (allocated[ptr] == 1) { 143 print NR ": " what " " ptr 144 #allocated[ptr] = 0 # stop the dangle 145 nd++ 146 } 147 } 148 if (nd > 0) print NR ": count " what " " nd 149 } 150 151 /^[mfr]/ { 152 ptr = $2 153 a1 = ($1 == "m")? 1: 0 154 a0 = 0+allocated[ptr] 155 allocated[ptr] = a1 156 if (a0 + a1 != 1) { 157 if (a0 == 0 && a1 == 0) 158 print NR ": double free " ptr 159 else if (a0 == 1 && a1 == 1) 160 print NR ": double malloc " ptr 161 else 162 print NR ": oddity " $0 163 } 164 next 165 } 166 167 /^s/ { 168 checkleaks("suspended") 169 next 170 } 171 172 { 173 print NR ": unrecognized " $0 174 } 175 END { 176 checkleaks("leaked") 177 } 178 ' 179 */ 180 #endif // USE_MTRACE