jdk/src/jdk.runtime/share/native/common-unpack/utils.cpp
changeset 29455 e451c01a5747
parent 29454 e5e9478e2ddb
parent 29433 c97e2d1bad97
child 29478 6637277d28cc
equal deleted inserted replaced
29454:e5e9478e2ddb 29455:e451c01a5747
     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, 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