utils.cpp revision 16278:de18c7fc80ea
1/* 2 * Copyright (c) 2001, 2015, 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 49void* 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 65void 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#ifndef STATIC_BUILD 81// use the definition in libjvm when building statically 82void breakpoint() { } // hook for debugger 83int assert_failed(const char* p) { 84 char message[1<<12]; 85 sprintf(message, "@assert failed: %s\n", p); 86 fprintf(stdout, "%s", 1+message); 87 breakpoint(); 88 unpack_abort(message); 89 return 0; 90} 91#endif 92#endif 93 94void unpack_abort(const char* msg, unpacker* u) { 95 if (msg == null) msg = "corrupt pack file or internal error"; 96 if (u == null) 97 u = unpacker::current(); 98 if (u == null) { 99 fprintf(stderr, "Error: unpacker: %s\n", msg); 100 ::abort(); 101 return; 102 } 103 u->abort(msg); 104} 105 106bool unpack_aborting(unpacker* u) { 107 if (u == null) 108 u = unpacker::current(); 109 if (u == null) { 110 fprintf(stderr, "Error: unpacker: no current instance\n"); 111 ::abort(); 112 return true; 113 } 114 return u->aborting(); 115} 116 117#ifdef USE_MTRACE 118// Use this occasionally for detecting storage leaks in unpack. 119void mtrace(char c, void* ptr, size_t size) { 120 if (c == 'f') *(int*)ptr = 0xbaadf00d; 121 static FILE* mtfp; 122 if (mtfp == (FILE*)-1) return; 123 if (mtfp == null) { 124 if (getenv("USE_MTRACE") == null) { 125 mtfp = (FILE*)-1; 126 return; 127 } 128 char fname[1024]; 129 sprintf(fname, "mtr%d.txt", getpid()); 130 mtfp = fopen(fname, "w"); 131 if (mtfp == null) 132 mtfp = stdout; 133 } 134 fprintf(mtfp, "%c %p %p\n", c, ptr, (void*)size); 135} 136 137/* # Script for processing memory traces. 138 # It should report only a limited number (2) of "suspended" blocks, 139 # even if a large number of archive segments are processed. 140 # It should report no "leaked" blocks at all. 141 nawk < mtr*.txt ' 142 function checkleaks(what) { 143 nd = 0 144 for (ptr in allocated) { 145 if (allocated[ptr] == 1) { 146 print NR ": " what " " ptr 147 #allocated[ptr] = 0 # stop the dangle 148 nd++ 149 } 150 } 151 if (nd > 0) print NR ": count " what " " nd 152 } 153 154 /^[mfr]/ { 155 ptr = $2 156 a1 = ($1 == "m")? 1: 0 157 a0 = 0+allocated[ptr] 158 allocated[ptr] = a1 159 if (a0 + a1 != 1) { 160 if (a0 == 0 && a1 == 0) 161 print NR ": double free " ptr 162 else if (a0 == 1 && a1 == 1) 163 print NR ": double malloc " ptr 164 else 165 print NR ": oddity " $0 166 } 167 next 168 } 169 170 /^s/ { 171 checkleaks("suspended") 172 next 173 } 174 175 { 176 print NR ": unrecognized " $0 177 } 178 END { 179 checkleaks("leaked") 180 } 181' 182*/ 183#endif // USE_MTRACE 184