root/modules/dbg_dump.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dbg_dump_write
  2. dbg_dump_assert

   1 #include "camera_info.h"
   2 #include "stdlib.h"
   3 #include "conf.h"
   4 #include "script.h"
   5 #include "meminfo.h"
   6 #include "cache.h"
   7 #include "module_load.h"
   8 #include "clock.h"
   9 #include "cachebit.h"
  10 
  11 // to keep format simple, we always write meminfo for each
  12 // but can skip actual getmeminfo since call might crash on mem corruption
  13 #define DBG_DUMP_FL_NOMEMINFO   0x1
  14 #define DBG_DUMP_FL_NOEXMEMINFO 0x2
  15 
  16 #define DBG_DUMP_VERSION        2 
  17 // version 2 - added module info, tick, uncached bit, max_ram_addr, build_string
  18 /*
  19 dump debug info to a file
  20 format
  21  header
  22  meminfo (camera heap, may be mostly -1 if meminfo not supported,0s if desabled)
  23  meminfo (exmem, 0s if exmem disabled)
  24  module info, length given by module_count * module_info_size
  25  stack dump (length in words given stack_count)
  26  user data (variable length given in user_data_len)
  27 */
  28 typedef struct {
  29     int ver;
  30     int time;
  31     int tick;
  32     int platform_id;
  33     int romstart;    // could look up the following 3 manually but makes auto parsing easier
  34     int uncached_bit;
  35     int max_ram_addr;
  36     int text_start; // == _start
  37     int data_start; // == text_end
  38     int bss_start;  // == data_end
  39     int bss_end;    // == _end
  40     int module_count; // number of loaded modules
  41     int module_info_size; // dump version should change if this changes, but will keep the rest of dump readable if it doesn't 
  42     int sp;
  43     int stack_count; // number of words of stack dumped (not related to number of words in stack!)
  44     int user_val; // user_data address if not null, otherwise treat user_data_size as an arbitrary int and put it here
  45     int user_data_len;
  46     int flags;
  47     char build_string[100]; // "platform,sub,date,time,version,rev", oversized for simplicity
  48 } dumpheader;
  49 
  50 typedef struct {
  51     int index;
  52     module_entry m;
  53     flat_hdr h;
  54 } mod_info;
  55 
  56 // this does not describe the structure, just a convenient way to access uncached + use less memory
  57 typedef union {
  58     dumpheader h;
  59     cam_meminfo m;
  60     mod_info mi;
  61 } dumpinfo;
  62 
  63 // number of words to dump -- could get initial SP from task
  64 #define STACK_DUMP_COUNT 512
  65 
  66 
  67 void dbg_dump_write(const char *dumpname,unsigned flags, int user_data_len, char *user_data) {
  68     static dumpinfo buf;
  69     // convenient access to uncached version
  70     dumpinfo *pb = ADR_TO_UNCACHED(&buf);
  71     
  72     // use open + uncached mem because we may not have enough memory for fopen
  73     int fd=open(dumpname, O_WRONLY|O_CREAT|O_TRUNC, 0777);
  74     if(fd >= 0) {
  75         int *sp;
  76         asm volatile( "MOV %0,SP\n" :"=r"(sp));
  77         pb->h.ver = DBG_DUMP_VERSION;
  78         pb->h.time = time(NULL);
  79         pb->h.tick = get_tick_count();
  80         pb->h.platform_id = conf.platformid;
  81         pb->h.romstart = camera_info.rombaseaddr;
  82         pb->h.uncached_bit = camera_info.cam_uncached_bit;
  83         pb->h.max_ram_addr = camera_info.maxramaddr;
  84         pb->h.text_start = camera_info.text_start;
  85         pb->h.data_start = camera_info.data_start;
  86         pb->h.bss_start = camera_info.bss_start;
  87         pb->h.bss_end = camera_info.bss_end;
  88         pb->h.sp = (int)sp;
  89         pb->h.stack_count = STACK_DUMP_COUNT;
  90         if(user_data) {
  91             pb->h.user_data_len = user_data_len;
  92             pb->h.user_val = (int)user_data;
  93         } else {
  94             pb->h.user_data_len = 0;
  95             pb->h.user_val = user_data_len;
  96         }
  97 
  98         pb->h.flags = flags;
  99 
 100         int m_count=0;
 101         // count so we can store it in the header
 102         int i;
 103         for(i=0;i<MAX_NUM_LOADED_MODULES;i++) {
 104             const module_entry *m = module_get_adr(i);
 105             if(m) {
 106                 m_count++;
 107             }
 108         }
 109         pb->h.module_count = m_count;
 110         pb->h.module_info_size = sizeof(mod_info);
 111         sprintf(pb->h.build_string,"%s,%s,%s,%s,%s,%s", 
 112                 camera_info.platform,
 113                 camera_info.platformsub,
 114                 camera_info.build_date,
 115                 camera_info.build_time,
 116                 camera_info.build_number,
 117                 camera_info.build_svnrev);
 118 
 119         write(fd,&pb->h,sizeof(dumpheader));
 120 
 121         if(!(flags & DBG_DUMP_FL_NOMEMINFO)) {
 122             GetMemInfo(&pb->m);
 123         } else {
 124             memset(&pb->m,0,sizeof(cam_meminfo));
 125         }
 126         write(fd,&pb->m,sizeof(cam_meminfo));
 127 
 128         // if no exmem don't check
 129         memset(&pb->m,0,sizeof(cam_meminfo));
 130         if(!(flags & DBG_DUMP_FL_NOEXMEMINFO)) {
 131             GetExMemInfo(&pb->m);
 132         }
 133         write(fd,&pb->m,sizeof(cam_meminfo));
 134 
 135         // assume modules haven't gone away since count, might not be valid?
 136         for(i=0;i<MAX_NUM_LOADED_MODULES;i++) {
 137             const module_entry *m = module_get_adr(i);
 138             if(!m) {
 139                 continue;
 140             }
 141             pb->mi.index = i;
 142             memcpy(&pb->mi.m,m,sizeof(module_entry));
 143             memcpy(&pb->mi.h,m->hdr,sizeof(flat_hdr));
 144             write(fd,&pb->mi,sizeof(mod_info));
 145         }
 146 
 147         // clean cache for write()
 148         dcache_clean_all();
 149 
 150         write(fd,ADR_TO_UNCACHED(sp),STACK_DUMP_COUNT*4);
 151         if(user_data_len && user_data) {
 152             // we assume user_data has been flushed out by preceding
 153             write(fd,ADR_TO_UNCACHED(user_data),user_data_len);
 154         }
 155         close(fd);
 156     } else {
 157         script_console_add_error( (long)"failed to open dump file" );
 158     }
 159 }
 160 
 161 void dbg_dump_assert(const char *dumpfile,const char *expr,const char *file,int line) {
 162     static char buf[128]; // could overflow if expr is long
 163     sprintf(buf,"ASSERT %s:%d %s",file,line,expr);
 164     script_console_add_error( (long)buf );
 165     dbg_dump_write(dumpfile,0,sizeof(buf),buf);
 166 }

/* [<][>][^][v][top][bottom][index][help] */