• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

CoreUtils.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026    CoreUtils.cc
00027 
00028    Description:  Automated processing of core files on Linux
00029  ****************************************************************************/
00030 
00031 
00032 /*
00033    Stack Unwinding procedure on ix86 architecture on Linux :
00034    Get the first frame pointer in $ebp.
00035    The value stored in $ebp is the address of prev frame pointer.
00036    Keep on unwinding till it is Ox0.
00037    $ebp+4 in each frame represents $eip.(PC)
00038 */
00039 
00040 /*
00041  *  Accessing arguments on 386 :
00042  *  ----------------------------
00043  *  We need to start from $ebp+4 and then keep on reading args
00044  *  till we reach the base pointer for prev. frame
00045  *
00046  *
00047  *        (high memory)
00048  *    +                     +
00049  *    | Callers Stack Frame |
00050  *    +---------------------+
00051  *    |   function call     |
00052  *    |     arguments       |
00053  *    +---------------------+
00054  *    |   Return Address    +
00055  *    +-------------------- +
00056  *    |    Old base pointer + Base pointer BP
00057  *    +-------------------- +
00058  *    |                     |
00059  *    |                     |
00060  *    |                     | Local (automatic) variables
00061  *    |                     |
00062  *    |                     |
00063  *    |                     |
00064  *    |                     |
00065  *    |                     |
00066  *    |                     |
00067  *    +---------------------+ Stack pointer SP
00068  *    |     free stack      | (low memory, top of the stack)
00069  *    |    begins here      |
00070  *    +                     +
00071  *
00072  *
00073  *        +-----------------+     +-----------------+
00074  *  FP -> | previous FP --------> | previous FP ------>...
00075  *        |                 |     |                 |
00076  *        | return address  |     | return address  |
00077  *        +-----------------+     +-----------------+
00078  */
00079 
00080 /*
00081    PORTING ISSUES:
00082    read_core_memory read_core_memory II read_heap_header not used
00083    -> figure out some way to make print_netstate useful!
00084 */
00085 
00086 /* 32-bit arguments are pushed down stack in reverse syntactic order (hence accessed/popped in the right order), above the 32-bit near return address. %ebp, %esi, %edi, %ebx are callee-saved, other registers are caller-saved; %eax is to hold the result, or %edx:%eax for 64-bit results */
00087 
00088 /*    has -fomit-frame-pointer has any repercussions??
00089       We assume that all the code is generated with frame pointers set.  */
00090 
00091 /* modify the "note" in process_core */
00092 /* Document properly */
00093 
00094 #include "ink_config.h"
00095 
00096 #if defined(linux)
00097 #include "CoreUtils.h"
00098 
00099 #define __p_type p_type         //ugly hack? - see resolv.h
00100 #define D(x) x                  /* for debugging */
00101 intptr_t f1, f2;
00102 int framepointer = 0;
00103 int program_counter = 0;
00104 #endif  // linux check
00105 
00106 #if defined(darwin) || defined(freebsd) || defined(solaris) || defined(openbsd) // FIXME: solaris x86
00107 // TODO: Cleanup multiple includes
00108 #include <stdio.h>
00109 #include <stdlib.h>
00110 #include <stdint.h>
00111 #include <math.h>
00112 #include "libts.h"
00113 #include "CoreUtils.h"
00114 #endif /* darwin || freebsd || solaris */
00115 
00116 #include "EventName.h"
00117 
00118 #include "http/HttpSM.h"
00119 
00120 bool inTable;
00121 FILE *fp;
00122 memTable default_memTable = { 0, 0, 0 };
00123 DynArray<struct memTable>arrayMem(&default_memTable, 0);
00124 
00125 HTTPHdrImpl *global_http;
00126 HttpSM *last_seen_http_sm = NULL;
00127 
00128 char ethread_ptr_str[256] = "";
00129 char netvc_ptr_str[256] = "";
00130 
00131 HdrHeap *swizzle_heap;
00132 char *ptr_data;
00133 
00134 
00135 // returns the index of the vaddr or the index after where it should be
00136 intptr_t
00137 CoreUtils::find_vaddr(intptr_t vaddr, intptr_t upper, intptr_t lower)
00138 {
00139   intptr_t index = (intptr_t) floor((double)((upper + lower) / 2));
00140 
00141   // match in table, returns index to be inserted into
00142   if (arrayMem[index].vaddr == vaddr) {
00143     inTable = true;
00144     return index + 1;
00145     // no match
00146   } else if (upper == lower) {
00147     inTable = false;
00148     return upper;
00149     // no match
00150   } else if (index == lower) {
00151     inTable = false;
00152     if ((index == 0) && (arrayMem[index].vaddr > vaddr))
00153       return 0;
00154     else
00155       return index + 1;
00156   } else {
00157     if (arrayMem[index].vaddr > vaddr)
00158       return find_vaddr(vaddr, index, lower);
00159     else
00160       return find_vaddr(vaddr, upper, index);
00161   }
00162   assert(0);
00163   return -1;
00164 }
00165 
00166 // inserts virtual address struct into the list
00167 void
00168 CoreUtils::insert_table(intptr_t vaddr1, intptr_t offset1, intptr_t fsize1)
00169 {
00170   // TODO: What was this intended for??
00171 #if 0
00172   memTable m;
00173   m.vaddr = vaddr1;
00174   m.offset = offset1;
00175   m.fsize = fsize1;
00176 #endif
00177 
00178   if (arrayMem.length() == 0) {
00179     arrayMem(0);
00180     arrayMem[(intptr_t)0].vaddr = vaddr1;
00181     arrayMem[(intptr_t)0].offset = offset1;
00182     arrayMem[(intptr_t)0].fsize = fsize1;
00183   } else {
00184     intptr_t index = find_vaddr(vaddr1, arrayMem.length(), 0);
00185     if (index == arrayMem.length()) {
00186       arrayMem(index);
00187       arrayMem[index].vaddr = vaddr1;
00188       arrayMem[index].offset = offset1;
00189       arrayMem[index].fsize = fsize1;
00190     } else if (index == 0) {
00191       arrayMem(arrayMem.length());
00192       for (intptr_t i = 0; i < arrayMem.length(); i++) {
00193         arrayMem[arrayMem.length() - i - 1].vaddr = arrayMem[arrayMem.length() - i - 2].vaddr;
00194         arrayMem[arrayMem.length() - i - 1].offset = arrayMem[arrayMem.length() - i - 2].offset;
00195         arrayMem[arrayMem.length() - i - 1].fsize = arrayMem[arrayMem.length() - i - 2].fsize;
00196       }
00197       arrayMem[(intptr_t)0].vaddr = vaddr1;
00198       arrayMem[(intptr_t)0].offset = offset1;
00199       arrayMem[(intptr_t)0].fsize = fsize1;
00200     } else {
00201       arrayMem(arrayMem.length());
00202       for (intptr_t i = 1; i < arrayMem.length() - index; i++) {
00203         arrayMem[arrayMem.length() - i].vaddr = arrayMem[arrayMem.length() - i - 1].vaddr;
00204         arrayMem[arrayMem.length() - i].offset = arrayMem[arrayMem.length() - i - 1].offset;
00205         arrayMem[arrayMem.length() - i].fsize = arrayMem[arrayMem.length() - i - 1].fsize;
00206       }
00207       arrayMem[index].vaddr = vaddr1;
00208       arrayMem[index].offset = offset1;
00209       arrayMem[index].fsize = fsize1;
00210     }
00211   }
00212 }
00213 
00214 
00215 // returns -1 if not found in table or fills the buffer with characters
00216 // from the beginning of the memory section
00217 intptr_t
00218 CoreUtils::read_core_memory(intptr_t vaddr, intptr_t length, char *buf, FILE * fp)
00219 {
00220   intptr_t index = find_vaddr(vaddr, arrayMem.length(), 0);
00221   if (inTable == false)
00222     return -1;
00223   else {
00224     intptr_t offset = arrayMem[index].offset;
00225 
00226     if (fseek(fp, offset, SEEK_SET) != -1) {
00227       for (int j = 0; j < length; j++) {
00228         *buf++ = (char) getc(fp);
00229       }
00230     }
00231     return 1;
00232   }
00233 }
00234 
00235 // returns -1 if not found in table or fills the buffer with characters
00236 // from the beginning of the memory section + offset
00237 intptr_t
00238 CoreUtils::read_core_memory(intptr_t offset, intptr_t vaddr, intptr_t length, char *buf, FILE * fp)
00239 {
00240   intptr_t index = find_vaddr(vaddr, arrayMem.length(), 0);
00241 
00242   if (inTable == false)
00243     return -1;
00244   else {
00245     intptr_t offset2 = arrayMem[index].offset;
00246 
00247     if (fseek(fp, offset2 + offset, SEEK_SET) != -1) {
00248       for (int j = 0; j < length; j++) {
00249         *buf++ = (char) getc(fp);
00250       }
00251     }
00252     return 1;
00253   }
00254 }
00255 
00256 
00257 // returns -1 on failure otherwise fills the buffer and
00258 // returns the number of bytes read
00259 intptr_t
00260 CoreUtils::read_from_core(intptr_t vaddr, intptr_t bytes, char *buf)
00261 {
00262   intptr_t index = find_vaddr(vaddr, arrayMem.length(), 0);
00263   intptr_t vadd = arrayMem[index - 1].vaddr;
00264   intptr_t offset = arrayMem[index - 1].offset;
00265   intptr_t size = arrayMem[index - 1].fsize;
00266   intptr_t offset2 = abs(vaddr - vadd);
00267 
00268   if (bytes > (size - offset2))
00269     return -1;
00270   else {
00271     if (fseek(fp, offset2 + offset, SEEK_SET) != -1) {
00272       char *frameoff;
00273       if ((frameoff = (char *)ats_malloc(sizeof(char) * bytes))) {
00274         if (fread(frameoff, bytes, 1, fp) == 1) {
00275           memcpy(buf, frameoff, bytes);
00276           /*for(int j =0; j < bytes; j++) {
00277            *buf++ = getc(fp);
00278            }
00279            buf -= bytes;*/
00280           ats_free(frameoff);
00281           return bytes;
00282         }
00283         ats_free(frameoff);
00284       }
00285     } else
00286       return -1;
00287   }
00288 
00289   return -1;
00290 }
00291 
00292 
00293 /* Linux Specific functions */
00294 
00295 #if defined(linux)
00296 // copies stack info for the thread's base frame to the given
00297 // core_stack_state pointer
00298 void
00299 CoreUtils::get_base_frame(intptr_t framep, core_stack_state *coress)
00300 {
00301   // finds vaddress less than framep
00302   intptr_t index = find_vaddr(framep, arrayMem.length(), 0);
00303   intptr_t vadd = arrayMem[index - 1].vaddr;
00304   intptr_t off = arrayMem[index - 1].offset;
00305   intptr_t off2 = abs(vadd - framep);
00306   intptr_t size = arrayMem[index - 1].fsize;
00307   intptr_t i = 0;
00308 
00309   memset(coress, 0, sizeof(*coress));
00310   D(printf("stkbase=%p\n", (void*)(vadd + size)));
00311   // seek to the framep offset
00312   if (fseek(fp, off + off2, SEEK_SET) != -1) {
00313     void **frameoff;
00314     if ((frameoff = (void **)ats_malloc(sizeof(long)))) {
00315       if (fread(frameoff, 4, 1, fp) == 1) {
00316         coress->framep = (intptr_t) *frameoff;
00317         if (fread(frameoff, 4, 1, fp) == 1) {
00318           coress->pc = (intptr_t) *frameoff;
00319         }
00320         // read register arguments
00321         for (i = 0; i < NO_OF_ARGS; i++) {
00322           if (fread(frameoff, 4, 1, fp) == 1) {
00323             coress->arg[i] = (intptr_t) *frameoff;
00324           }
00325         }
00326       }
00327       ats_free(frameoff);
00328     }
00329   } else {
00330     printf("Failed to seek to top of the stack\n");
00331   }
00332   //coress->stkbase = vadd+size;
00333 }
00334 
00335 // returns 0 if current frame is already at the top of the stack
00336 // or returns 1 and moves up the stack once
00337 int
00338 CoreUtils::get_next_frame(core_stack_state * coress)
00339 {
00340   intptr_t i = 0;
00341   intptr_t framep = coress->framep;
00342 
00343   intptr_t index = find_vaddr(framep, arrayMem.length(), 0);
00344 
00345   // finds vaddress less than framep
00346   intptr_t vadd = arrayMem[index - 1].vaddr;
00347   intptr_t off = arrayMem[index - 1].offset;
00348   intptr_t off2 = abs(vadd - framep);
00349 
00350   // seek to the framep offset
00351   if (fseek(fp, off + off2, SEEK_SET) != -1) {
00352     void **frameoff;
00353     if ((frameoff = (void **)ats_malloc(sizeof(long)))) {
00354       if (fread(frameoff, 4, 1, fp) == 1) {
00355         coress->framep = (intptr_t) *frameoff;
00356         if (*frameoff == NULL) {
00357           ats_free(frameoff);
00358           return 0;
00359         }
00360         if (fread(frameoff, 4, 1, fp) == 1) {
00361           coress->pc = (intptr_t) *frameoff;
00362         }
00363         for (i = 0; i < NO_OF_ARGS; i++) {
00364           if (fread(frameoff, 4, 1, fp) == 1) {
00365             coress->arg[i] = (intptr_t) *frameoff;
00366           }
00367         }
00368       }
00369       ats_free(frameoff);
00370     }
00371     return 1;
00372   }
00373 
00374   return 0;
00375 }
00376 
00377 // prints the http header
00378 void
00379 CoreUtils::find_stuff(StuffTest_f f)
00380 {
00381   intptr_t framep = framepointer;
00382   intptr_t pc = program_counter;
00383   core_stack_state coress;
00384   intptr_t i;
00385   void *test_val;
00386   int framecount = 0;
00387 
00388   // Unwinding the stack
00389   D(printf("\nStack Trace:\n"));
00390   D(printf("stack frame#%d framep=%p pc=%p\n", framecount, (void*)framep, (void*)pc));
00391   framecount++;
00392   get_base_frame(framep, &coress);
00393   f2 = framep;
00394   do {
00395     f1 = f2;
00396     f2 = coress.framep;
00397     D(printf
00398       ("stack frame#%d framep=%p pc=%p f1-f2=%p coress=%p %p %p %p %p\n", framecount, (void*)coress.framep, (void*)coress.pc,
00399        (void*)(f2 - f1), (void*)coress.arg[0], (void*)coress.arg[1], (void*)coress.arg[2], (void*)coress.arg[3], (void*)coress.arg[4]));
00400 
00401     for (i = 0; i < NO_OF_ARGS; i++) {
00402       test_val = (void *) coress.arg[i];
00403       f(test_val);
00404     }
00405     framecount++;
00406   } while (get_next_frame(&coress) != 0);
00407 }
00408 #endif  // linux check
00409 
00410 
00411 // test whether a given register is an HttpSM
00412 //   if it is, call process_HttpSM on it
00413 void
00414 CoreUtils::test_HdrHeap(void *arg)
00415 {
00416   HdrHeap *hheap_test = (HdrHeap *) arg;
00417   uint32_t *magic_ptr = &(hheap_test->m_magic);
00418   uint32_t magic = 0;
00419 
00420   if (read_from_core((intptr_t) magic_ptr, sizeof(uint32_t), (char *) &magic) != 0) {
00421     if (magic == HDR_BUF_MAGIC_ALIVE ||
00422         magic == HDR_BUF_MAGIC_DEAD || magic == HDR_BUF_MAGIC_CORRUPT || magic == HDR_BUF_MAGIC_MARSHALED) {
00423       // This is not 64-bit correct ... /leif
00424       printf("Found Hdr Heap @ 0x%p\n", arg);
00425     }
00426   }
00427 }
00428 
00429 // test whether a given register is an HttpSM
00430 //   if it is, call process_HttpSM on it
00431 //
00432 // This code generates errors from Clang, on hsm_test not being initialized
00433 // properly. Currently this is not used, so ifdef'ing out to suppress.
00434 #ifndef __clang_analyzer__
00435 void
00436 CoreUtils::test_HttpSM_from_tunnel(void *arg)
00437 {
00438   char *tmp = (char *) arg;
00439   intptr_t offset = (intptr_t) &(((HttpTunnel *) NULL)->sm);
00440   HttpSM **hsm_ptr = (HttpSM **) (tmp + offset);
00441   HttpSM *hsm_test;
00442 
00443   if (read_from_core((intptr_t) hsm_ptr, sizeof(HttpSM *), (char *) &hsm_test) == 0)
00444     return;
00445 
00446   unsigned int *magic_ptr = &(hsm_test->magic);
00447   unsigned int magic = 0;
00448 
00449   if (read_from_core((intptr_t) magic_ptr, sizeof(int), (char *) &magic) != 0) {
00450     if (magic == HTTP_SM_MAGIC_ALIVE || magic == HTTP_SM_MAGIC_DEAD) {
00451       process_HttpSM(hsm_test);
00452     }
00453   }
00454 }
00455 #endif
00456 
00457 // test whether a given register is an HttpSM
00458 //   if it is, call process_HttpSM on it
00459 void
00460 CoreUtils::test_HttpSM(void *arg)
00461 {
00462   HttpSM *hsm_test = (HttpSM *) arg;
00463   unsigned int *magic_ptr = &(hsm_test->magic);
00464   unsigned int magic = 0;
00465 
00466   if (read_from_core((intptr_t) magic_ptr, sizeof(int), (char *) &magic) != 0) {
00467     if (magic == HTTP_SM_MAGIC_ALIVE || magic == HTTP_SM_MAGIC_DEAD) {
00468       printf("test_HttpSM:******MATCH*****\n");
00469       process_HttpSM(hsm_test);
00470     }
00471   }
00472 }
00473 
00474 void
00475 CoreUtils::process_HttpSM(HttpSM * core_ptr)
00476 {
00477   // extracting the HttpSM from the core file
00478   if (last_seen_http_sm != core_ptr) {
00479     HttpSM *http_sm = (HttpSM *)ats_malloc(sizeof(HttpSM));
00480 
00481     if (read_from_core((intptr_t) core_ptr, sizeof(HttpSM), (char *) http_sm) < 0) {
00482       // This is not 64-bit correct ... /leif
00483       printf("ERROR: Failed to read httpSM @ 0x%p from core\n", core_ptr);
00484       ats_free(http_sm);
00485       return;
00486     }
00487 
00488     if (http_sm->magic == HTTP_SM_MAGIC_ALIVE) {
00489       last_seen_http_sm = core_ptr;
00490 
00491       if (is_debug_tag_set("magic")) {
00492 #if defined(linux)
00493         printf("\n*****match-ALIVE*****\n");
00494 #endif
00495       }
00496       // I don't think this is 64-bit correct. /leif
00497       printf("---- Found HttpSM --- id %" PRId64 "  ------ @ 0x%p -----\n\n", http_sm->sm_id, http_sm);
00498 
00499       print_http_hdr(&http_sm->t_state.hdr_info.client_request, "Client Request");
00500       print_http_hdr(&http_sm->t_state.hdr_info.server_request, "Server Request");
00501       print_http_hdr(&http_sm->t_state.hdr_info.server_response, "Server Response");
00502       print_http_hdr(&http_sm->t_state.hdr_info.client_response, "Client Response");
00503 
00504       dump_history(http_sm);
00505 
00506       printf("------------------------------------------------\n\n\n");
00507     } else if (http_sm->magic == HTTP_SM_MAGIC_DEAD) {
00508       if (is_debug_tag_set("magic")) {
00509 #if defined(linux)
00510         printf("\n*****match-DEAD*****\n");
00511 #endif
00512       }
00513     } else {
00514       if (is_debug_tag_set("magic")) {
00515         // Nothing here? /leif
00516         ;
00517       }
00518     }
00519 
00520     ats_free(http_sm);
00521   } else
00522     printf("process_HttpSM : last_seen_http_sm == core_ptr\n");
00523 }
00524 
00525 
00526 void
00527 CoreUtils::print_http_hdr(HTTPHdr * h, const char *name)
00528 {
00529   HTTPHdr new_handle;
00530 
00531   if (h->m_heap && h->m_http) {
00532     int r = load_http_hdr(h, &new_handle);
00533 
00534     if (r > 0) {
00535       printf("----------- %s  ------------\n", name);
00536       new_handle.m_mime = new_handle.m_http->m_fields_impl;
00537       new_handle.print(NULL, 0, NULL, NULL);
00538       printf("-----------------------------\n\n");
00539     }
00540   }
00541 }
00542 
00543 int
00544 CoreUtils::load_http_hdr(HTTPHdr * core_hdr, HTTPHdr * live_hdr)
00545 {
00546   // Load HdrHeap chain
00547   HTTPHdr *http_hdr = core_hdr;
00548   HdrHeap *heap = (HdrHeap *) core_hdr->m_heap;
00549   HdrHeap *heap_ptr = (HdrHeap *) http_hdr->m_heap;
00550   char *buf = (char *)ats_malloc(sizeof(char) * sizeof(HdrHeap));
00551   intptr_t ptr_heaps = 0;
00552   intptr_t ptr_heap_size = 0;
00553   intptr_t ptr_xl_size = 2;
00554   intptr_t str_size = 0;
00555   intptr_t str_heaps = 0;
00556   MarshalXlate default_MarshalXlate = { 0, 0, 0 };
00557   DynArray<struct MarshalXlate>ptr_xlation(&default_MarshalXlate, 2);
00558   //MarshalXlate static_table[2];
00559   //MarshalXlate* ptr_xlation = static_table;
00560   intptr_t used;
00561   intptr_t i;
00562   intptr_t copy_size;
00563 
00564   // extracting the header heap from the core file
00565   do {
00566     if (read_from_core((intptr_t) heap, sizeof(HdrHeap), buf) == -1) {
00567       printf("Cannot read from core\n");
00568       _exit(0);
00569     }
00570     heap = (HdrHeap *) buf;
00571     copy_size = (int) (heap->m_free_start - heap->m_data_start);
00572     ptr_heap_size += copy_size;
00573     heap = heap->m_next;
00574   } while (heap && ((intptr_t) heap != 0x1));
00575 
00576   swizzle_heap = (HdrHeap *)ats_malloc(sizeof(HdrHeap));
00577   live_hdr->m_heap = swizzle_heap;
00578   ptr_data = (char *)ats_malloc(sizeof(char) * ptr_heap_size);
00579   //heap = (HdrHeap*)http_hdr->m_heap;
00580 
00581   //  Build Hdr Heap Translation Table
00582   do {
00583     if (read_from_core((intptr_t) heap_ptr, sizeof(HdrHeap), buf) == -1) {
00584       printf("Cannot read from core\n");
00585       _exit(0);
00586     }
00587     heap_ptr = (HdrHeap *) buf;
00588     copy_size = (int) (heap_ptr->m_free_start - heap_ptr->m_data_start);
00589 
00590     if (read_from_core((intptr_t) heap_ptr->m_data_start, copy_size, ptr_data) == -1) {
00591       printf("Cannot read from core\n");
00592       _exit(0);
00593     }
00594     // Expand ptr xlation table if necessary
00595     if (ptr_heaps >= ptr_xl_size) {
00596       ptr_xlation(ptr_heaps);
00597     }
00598 
00599     char *data, *free, *off;
00600     data = heap_ptr->m_data_start;
00601     free = heap_ptr->m_free_start;
00602     off = (char *) (heap_ptr->m_data_start - ptr_data);
00603 
00604     ptr_xlation[ptr_heaps].start = data;
00605     ptr_xlation[ptr_heaps].end = free;
00606     ptr_xlation[ptr_heaps].offset = off;
00607     ptr_data += copy_size;
00608     ptr_heaps++;
00609     heap_ptr = heap_ptr->m_next;
00610   } while (heap_ptr && ((intptr_t) heap_ptr != 0x1));
00611 
00612   heap = (HdrHeap *) http_hdr->m_heap;
00613   if (read_from_core((intptr_t) heap, sizeof(HdrHeap), buf) == -1) {
00614     printf("Cannot read from core\n");
00615     _exit(0);
00616   }
00617   heap = (HdrHeap *) buf;
00618   // filling in the live_hdr
00619   swizzle_heap->m_free_start = NULL;
00620   swizzle_heap->m_data_start = (char *) ptr_data - ptr_heap_size;       // offset
00621   swizzle_heap->m_magic = HDR_BUF_MAGIC_ALIVE;
00622   swizzle_heap->m_writeable = false;
00623   swizzle_heap->m_size = ptr_heap_size;
00624   swizzle_heap->m_next = NULL;
00625   swizzle_heap->m_free_size = 0;
00626   swizzle_heap->m_read_write_heap.m_ptr = NULL;
00627 
00628   // We'have one read-only string heap after marshalling
00629   swizzle_heap->m_ronly_heap[0].m_heap_start = (char *)(intptr_t)swizzle_heap->m_size;   // offset
00630   swizzle_heap->m_ronly_heap[0].m_ref_count_ptr.m_ptr = NULL;
00631 
00632   for (int i = 1; i < HDR_BUF_RONLY_HEAPS; i++)
00633     swizzle_heap->m_ronly_heap[i].m_heap_start = NULL;
00634 
00635   // Next order of business is to copy over string heaps
00636   //   As we are copying over the string heaps, build
00637   //   translation table for string marshaling in the heap
00638   //   objects
00639   MarshalXlate str_xlation[HDR_BUF_RONLY_HEAPS + 1];
00640 
00641   // Local String Heaps, building translation table
00642   if (heap->m_read_write_heap) {
00643     HdrStrHeap *hdr = (HdrStrHeap *) heap->m_read_write_heap.m_ptr;
00644     char *copy_start = ((char *) heap->m_read_write_heap.m_ptr) + sizeof(HdrStrHeap);
00645     char *str_hdr = (char *)ats_malloc(sizeof(char) * sizeof(HdrStrHeap));
00646     if (read_from_core((intptr_t) hdr, sizeof(HdrStrHeap), str_hdr) == -1) {
00647       printf("Cannot read from core\n");
00648       _exit(0);
00649     }
00650 
00651     char *free_start = (char *) (((HdrStrHeap *) str_hdr)->m_free_start);
00652     int nto_copy = abs((char *) copy_start - free_start);
00653     ats_free(str_hdr);
00654 #if defined(__GNUC__)
00655     char rw_heap[sizeof(char) * nto_copy];
00656 #else
00657     char *rw_heap = (char *)ats_malloc(sizeof(char) * nto_copy);
00658 #endif
00659     if (read_from_core((intptr_t) copy_start, nto_copy, rw_heap) == -1) {
00660       printf("Cannot read from core\n");
00661       _exit(0);
00662     }
00663     // FIX ME - possible offset overflow issues?
00664     str_xlation[str_heaps].start = copy_start;
00665     str_xlation[str_heaps].end = copy_start + nto_copy;
00666     str_xlation[str_heaps].offset = (char *) (copy_start - rw_heap);
00667 
00668     str_size += nto_copy;
00669     str_heaps++;
00670 #if !defined(__GNUC__)
00671     ats_free(rw_heap);
00672 #endif
00673   }
00674 
00675   for (i = 0; i < HDR_BUF_RONLY_HEAPS; i++) {
00676     if (heap->m_ronly_heap[i].m_heap_start != NULL) {
00677 #if defined(__GNUC__)
00678       char ro_heap[sizeof(char) * heap->m_ronly_heap[i].m_heap_len];
00679 #else
00680       char * ro_heap = (char *)ats_malloc(sizeof(char) * heap->m_ronly_heap[i].m_heap_len);
00681 #endif
00682       if (read_from_core((intptr_t) heap->m_ronly_heap[i].m_heap_start, heap->m_ronly_heap[i].m_heap_len, ro_heap) == -1) {
00683         printf("Cannot read from core\n");
00684         _exit(0);
00685       }
00686       // Add translation table entry for string heaps
00687       str_xlation[str_heaps].start = heap->m_ronly_heap[i].m_heap_start;
00688       str_xlation[str_heaps].end = heap->m_ronly_heap[i].m_heap_start + heap->m_ronly_heap[i].m_heap_len;
00689       str_xlation[str_heaps].offset = (char *) (heap->m_ronly_heap[i].m_heap_start - ro_heap);
00690 
00691       ink_assert(str_xlation[str_heaps].start <= str_xlation[str_heaps].end);
00692 
00693       str_heaps++;
00694       str_size += heap->m_ronly_heap[i].m_heap_len;
00695 #if !defined(__GNUC__)
00696       ats_free(ro_heap);
00697 #endif
00698     }
00699   }
00700 
00701   // Patch the str heap len
00702   swizzle_heap->m_ronly_heap[0].m_heap_len = str_size;
00703 
00704   char *obj_data = swizzle_heap->m_data_start;
00705   char *mheap_end = swizzle_heap->m_data_start + swizzle_heap->m_size;
00706 
00707   while (obj_data < mheap_end) {
00708     HdrHeapObjImpl *obj = (HdrHeapObjImpl *) obj_data;
00709     ink_assert(obj_is_aligned(obj));
00710 
00711     switch (obj->m_type) {
00712     case HDR_HEAP_OBJ_URL:
00713       if (((URLImpl *) obj)->marshal(str_xlation, str_heaps) < 0) {
00714         goto Failed;
00715       }
00716       break;
00717     case HDR_HEAP_OBJ_HTTP_HEADER:
00718       if (((HTTPHdrImpl *) obj)->marshal(ptr_xlation, ptr_heaps, str_xlation, str_heaps) < 0) {
00719         goto Failed;
00720       }
00721       live_hdr->m_http = (HTTPHdrImpl *) obj;
00722       break;
00723     case HDR_HEAP_OBJ_FIELD_BLOCK:
00724       if (((MIMEFieldBlockImpl *) obj)->marshal(ptr_xlation, ptr_heaps, str_xlation, str_heaps) < 0) {
00725         goto Failed;
00726       }
00727       break;
00728     case HDR_HEAP_OBJ_MIME_HEADER:
00729       if (((MIMEHdrImpl *) obj)->marshal(ptr_xlation, ptr_heaps, str_xlation, str_heaps)) {
00730         goto Failed;
00731       }
00732       break;
00733     case HDR_HEAP_OBJ_EMPTY:
00734       break;
00735     case HDR_HEAP_OBJ_RAW:
00736       // Check to make sure we aren't stuck
00737       //   in an infinite loop
00738       if (obj->m_length <= 0) {
00739         ink_assert(0);
00740         goto Failed;
00741       }
00742       // Nothing to do
00743       break;
00744     default:
00745       ink_release_assert(0);
00746     }
00747     obj_data = obj_data + obj->m_length;
00748   }
00749 
00750   // Add up the total bytes used
00751   used = ptr_heap_size + str_size + HDR_HEAP_HDR_SIZE;
00752   used = ROUND(used, HDR_PTR_SIZE);
00753 
00754   return used;
00755 
00756 Failed:
00757   swizzle_heap->m_magic = HDR_BUF_MAGIC_CORRUPT;
00758   return -1;
00759 
00760 }
00761 
00762 void
00763 CoreUtils::dump_history(HttpSM * hsm)
00764 {
00765   printf("-------- Begin History -------------\n");
00766 
00767   // Loop through the history and dump it
00768   for (int i = 0; i < hsm->history_pos; i++) {
00769     int r = (int) hsm->history[i].reentrancy;
00770     int e = (int) hsm->history[i].event;
00771     char *fileline = load_string(hsm->history[i].fileline);
00772 
00773     fileline = (fileline != NULL) ? fileline : ats_strdup("UNKNOWN");
00774 
00775     printf("%d   %d   %s", e, r, fileline);
00776 
00777     char buffer[32];
00778     const char *msg = event_int_to_string(e, sizeof(buffer), buffer);
00779     printf("   event string: \"%s\"\n", msg);
00780 
00781     ats_free(fileline);
00782   }
00783 
00784   printf("-------- End History -----------\n\n");
00785 }
00786 
00787 intptr_t
00788 CoreUtils::read_heap_header(intptr_t vaddr, intptr_t bytes, HdrHeap h)
00789 {
00790   intptr_t index = find_vaddr(vaddr, arrayMem.length(), 0);
00791   intptr_t vadd = arrayMem[index - 1].vaddr;
00792   intptr_t offset = arrayMem[index - 1].offset;
00793   intptr_t size = arrayMem[index - 1].fsize;
00794   intptr_t offset2 = abs(vaddr - vadd);
00795 
00796   if (bytes > (size - offset2))
00797     return -1;
00798   else {
00799     if (fseek(fp, offset2 + offset, SEEK_SET) != -1) {
00800       if (fread(&h, sizeof(HdrHeap), 1, fp) > 0)
00801         return bytes;
00802       else
00803         return -1;
00804     }
00805   }
00806   return -1;
00807 }
00808 
00809 void
00810 CoreUtils::process_EThread(EThread * eth_test)
00811 {
00812   char *buf = (char *)ats_malloc(sizeof(char) * sizeof(EThread));
00813 
00814   if (read_from_core((intptr_t) eth_test, sizeof(EThread), buf) != -1) {
00815     EThread *loaded_eth = (EThread *) buf;
00816 
00817     // This is not 64-bit correct. /leif
00818     printf("----------- EThread @ 0x%p ----------\n", eth_test);
00819 #if !defined(kfreebsd) && (defined(freebsd) || defined(darwin) || defined(openbsd))
00820     printf("   thread_id: %p\n", loaded_eth->tid);
00821 #else
00822     printf("   thread_id: %i\n", (int) loaded_eth->tid);
00823 #endif
00824     //    printf("   NetHandler: 0x%x\n\n", (int) loaded_eth->netHandler);
00825   }
00826 
00827   ats_free(buf);
00828 }
00829 
00830 static void
00831 print_netstate(NetState * n)
00832 {
00833   // These might not be 64-bit correct. /leif
00834   printf("      enabled: %d\n", n->enabled);
00835   printf("      op: %d  _cont: 0x%p\n", n->vio.op, n->vio._cont);
00836   printf("      nbytes: %d  done: %d\n", (int)n->vio.nbytes, (int)n->vio.ndone);
00837   printf("      vc_server: 0x%p   mutex: 0x%p\n\n", n->vio.vc_server, n->vio.mutex.m_ptr);
00838 }
00839 
00840 void
00841 CoreUtils::process_NetVC(UnixNetVConnection * nvc_test)
00842 {
00843   char *buf = (char *)ats_malloc(sizeof(char) * sizeof(UnixNetVConnection));
00844 
00845   if (read_from_core((intptr_t) nvc_test, sizeof(UnixNetVConnection), buf) != -1) {
00846     UnixNetVConnection *loaded_nvc = (UnixNetVConnection *) buf;
00847     
00848     // Probably not 64-bit safe. /leif
00849     char addrbuf[INET6_ADDRSTRLEN];
00850     printf("----------- UnixNetVConnection @ 0x%p ----------\n", nvc_test);
00851     printf("     ip: %s    port: %d\n",
00852         ats_ip_ntop(&loaded_nvc->server_addr.sa, addrbuf, sizeof(addrbuf)), 
00853         ats_ip_port_host_order(&loaded_nvc->server_addr));
00854     printf("     closed: %d\n\n", loaded_nvc->closed);
00855     printf("     read state: \n");
00856     print_netstate(&loaded_nvc->read);
00857     printf("     write state: \n");
00858     print_netstate(&loaded_nvc->write);
00859   }
00860 
00861   ats_free(buf);
00862 }
00863 
00864 
00865 char *
00866 CoreUtils::load_string(const char *addr)
00867 {
00868   char buf[2048];
00869   int index = 0;
00870 
00871   if (addr == NULL) {
00872     return ats_strdup("NONE");
00873   }
00874 
00875   while (index < 2048) {
00876     if (read_from_core((intptr_t) (addr + index), 1, buf + index) < 0) {
00877       return NULL;
00878     }
00879 
00880     if (buf[index] == '\0') {
00881       return ats_strdup(buf);
00882     }
00883     index++;
00884   }
00885 
00886   return NULL;
00887 }
00888 
00889 // parses core file
00890 #if defined(linux)
00891 void
00892 process_core(char *fname)
00893 {
00894   Elf32_Ehdr ehdr;
00895   Elf32_Phdr phdr;
00896   int phoff, phnum, phentsize;
00897   int framep = 0, pc = 0;
00898 
00899   /* Open the input file */
00900   if (!(fp = fopen(fname, "r"))) {
00901     printf("cannot open file\n");
00902     _exit(1);
00903   }
00904 
00905   /* Obtain the .shstrtab data buffer */
00906   if (fread(&ehdr, sizeof ehdr, 1, fp) != 1) {
00907     printf("Unable to read ehdr\n");
00908     _exit(1);
00909   }
00910   // program header offset
00911   phoff = ehdr.e_phoff;
00912   // number of program headers
00913   phnum = ehdr.e_phnum;
00914   // size of each program header
00915   phentsize = ehdr.e_phentsize;
00916 
00917   for (int i = 0; i < phnum; i++) {
00918     if (fseek(fp, phoff + i * phentsize, SEEK_SET) == -1) {
00919       fprintf(stderr, "Unable to seek to Phdr %d\n", i);
00920       _exit(1);
00921     }
00922 
00923     if (fread(&phdr, sizeof phdr, 1, fp) != 1) {
00924       fprintf(stderr, "Unable to read Phdr %d\n", i);
00925       _exit(1);
00926     }
00927     int poffset, psize;
00928     int pvaddr;
00929     /* This member gives the virtual address at which the first byte of the
00930        segment resides in memory. */
00931     pvaddr = phdr.p_vaddr;
00932     /* This member gives the offset from the beginning of the file at which
00933        the first byte of the segment resides. */
00934     poffset = phdr.p_offset;
00935     /* This member gives the number of bytes in the file image of the
00936        segment; it may be zero. */
00937     psize = phdr.p_filesz;
00938 
00939     if (pvaddr != 0) {
00940       CoreUtils::insert_table(pvaddr, poffset, psize);
00941     }
00942 
00943     if (is_debug_tag_set("phdr")) {
00944       printf("\n******* PHDR %d *******\n", i);
00945       printf("p_type = %u  ", phdr.p_type);
00946       printf("p_offset = %u  ", phdr.p_offset);
00947       printf("p_vaddr = %#x  ", pvaddr);
00948 
00949       printf("p_paddr = %#x\n", phdr.p_paddr);
00950       printf("p_filesz = %u  ", phdr.p_filesz);
00951       printf("p_memsz = %u  ", phdr.p_memsz);
00952       printf("p_flags = %u  ", phdr.p_flags);
00953       printf("p_align = %u\n", phdr.p_align);
00954     }
00955 
00956     if (phdr.p_type == PT_NOTE) {
00957       printf("NOTE\n");
00958       if (fseek(fp, phdr.p_offset, SEEK_SET) != -1) {
00959         Elf32_Nhdr *nhdr, *thdr;
00960         if ((nhdr = (Elf32_Nhdr *)ats_malloc(sizeof(Elf32_Nhdr) * phdr.p_filesz))) {
00961           if (fread(nhdr, phdr.p_filesz, 1, fp) == 1) {
00962             int size = phdr.p_filesz;
00963             int sum = 0;
00964             thdr = nhdr;
00965             while (size) {
00966               int len;
00967 
00968               len = sizeof *thdr + ((thdr->n_namesz + 3) & ~3) + ((thdr->n_descsz + 3) & ~3);
00969               // making sure the offset is byte aligned
00970               char *offset = (char *) (thdr + 1) + ((thdr->n_namesz + 3) & ~3);
00971 
00972               if (len<0 || len> size) {
00973                 _exit(1);
00974               }
00975               printf("size=%d, len=%d\n", size, len);
00976 
00977               prstatus_t pstat;
00978               prstatus_t *ps;
00979               prpsinfo_t infostat, *ist;
00980               elf_gregset_t rinfo;
00981               unsigned int j;
00982 
00983               switch (thdr->n_type) {
00984 
00985               case NT_PRSTATUS:
00986                 ps = (prstatus_t *) offset;
00987                 memcpy(&pstat, ps, sizeof(prstatus_t));
00988                 printf("\n*** printing registers****\n");
00989                 for (j = 0; j < ELF_NGREG; j++) {
00990                   rinfo[j] = pstat.pr_reg[j];
00991                   // This is probably not 64-bit correct. /leif
00992                   printf("%#x ", (unsigned int) rinfo[j]);
00993                 }
00994                 printf("\n");
00995 
00996                 //if (is_debug_tag_set("note")) {
00997                 printf("\n**** NT_PRSTATUS ****\n");
00998 
00999                 printf("Process id = %d\n", pstat.pr_pid);
01000                 printf("Parent Process id = %d\n", pstat.pr_ppid);
01001 
01002                 printf("Signal that caused this core dump is signal  = %d\n", pstat.pr_cursig);
01003                 // convert it using strsignal
01004                 //char *msg=strsignal(pstat.pr_cursig);
01005 
01006                 // Probably not 64-bit correct. /leif
01007                 printf("stack pointer = %#x\n", (unsigned int) pstat.pr_reg[SP_REGNUM]);        //UESP
01008                 framep = pstat.pr_reg[FP_REGNUM];
01009                 pc = pstat.pr_reg[PC_REGNUM];
01010                 // Probably not 64-bit correct. /leif
01011                 printf("frame pointer = %#x\n", (unsigned int) pstat.pr_reg[FP_REGNUM]);        //EBP
01012                 printf("program counter if no save = %#x\n", (unsigned int) pstat.pr_reg[PC_REGNUM]);
01013                 //}
01014                 break;
01015 
01016               case NT_PRPSINFO:
01017                 ist = (prpsinfo_t *) offset;
01018                 memcpy(&infostat, ist, sizeof(prpsinfo_t));
01019 
01020                 if (is_debug_tag_set("note")) {
01021                   printf("\n**** NT_PRPSINFO of active process****\n");
01022                   printf("process state = %c\n", infostat.pr_state);
01023                   printf("Name of the executable = %s\n", infostat.pr_fname);
01024                   printf("Arg List = %s\n", infostat.pr_psargs);
01025 
01026                   printf("process id = %d\n", infostat.pr_pid);
01027                 }
01028                 break;
01029               }
01030               thdr = (Elf32_Nhdr *) ((char *) thdr + len);
01031               sum += len;
01032               size -= len;
01033             }
01034           }
01035           ats_free(nhdr);
01036         }
01037       }
01038     }
01039   }
01040   framepointer = framep;
01041   program_counter = pc;
01042 
01043   // Write your actual tests here
01044   CoreUtils::find_stuff(&CoreUtils::test_HdrHeap);
01045   CoreUtils::find_stuff(&CoreUtils::test_HttpSM);
01046 
01047   fclose(fp);
01048 }
01049 #endif
01050 
01051 #if !defined(linux)
01052 void
01053 process_core(char *fname)
01054 {
01055   // do not make it fatal!!!!
01056   Warning("Only supported on Sparc Solaris and Linux");
01057 }
01058 #endif

Generated by  doxygen 1.7.1