#include "bcsignals.h"
#include "bcwindowbase.h"
+#include "bccmodels.h"
#include "bckeyboard.h"
+#include "bcresources.h"
+#include "cstrdup.h"
#include <ctype.h>
#include <dirent.h>
#include <execinfo.h>
+#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
BC_Signals* BC_Signals::global_signals = 0;
static int signal_done = 0;
-static int table_id = 0;
-
-static bc_locktrace_t* new_bc_locktrace(void *ptr,
- const char *title,
- const char *location)
-{
- bc_locktrace_t *result = (bc_locktrace_t*)malloc(sizeof(bc_locktrace_t));
- result->ptr = ptr;
- result->title = title;
- result->location = location;
- result->is_owner = 0;
- result->id = table_id++;
- result->tid = pthread_self();
- return result;
-}
-
static struct sigaction old_segv = {0, }, old_intr = {0, };
static void handle_dump(int n, siginfo_t * info, void *sc);
v = trap_sigintr;
}
-typedef struct
-{
- int size;
- void *ptr;
- const char *location;
-} bc_buffertrace_t;
-
-static bc_buffertrace_t* new_bc_buffertrace(int size, void *ptr, const char *location)
-{
- bc_buffertrace_t *result = (bc_buffertrace_t*)malloc(sizeof(bc_buffertrace_t));
- result->size = size;
- result->ptr = ptr;
- result->location = location;
- return result;
-}
-
-static void bc_copy_textfile(FILE *ofp, const char *fmt,...)
+static void bc_copy_textfile(int lines, FILE *ofp, const char *fmt,...)
{
va_list ap; va_start(ap, fmt);
char bfr[BCTEXTLEN]; vsnprintf(bfr, sizeof(bfr), fmt, ap);
va_end(ap);
FILE *ifp = fopen(bfr,"r");
if( !ifp ) return;
- while( fgets(bfr,sizeof(bfr),ifp) ) fputs(bfr,ofp);
+ while( --lines >= 0 && fgets(bfr,sizeof(bfr),ifp) ) fputs(bfr,ofp);
fclose(ifp);
}
-
-// Need our own table to avoid recursion with the memory manager
-typedef struct
-{
- void **values;
- int size;
- int allocation;
-// This points to the next value to replace if the table wraps around
- int current_value;
-} bc_table_t;
-
-static void* append_table(bc_table_t *table, void *ptr)
+static void bc_list_openfiles(int lines, FILE *ofp, const char *fmt,...)
{
- if(table->allocation <= table->size)
- {
- if(table->allocation)
- {
- int new_allocation = table->allocation * 2;
- void **new_values = (void**)calloc(new_allocation, sizeof(void*));
- memcpy(new_values, table->values, sizeof(void*) * table->size);
- free(table->values);
- table->values = new_values;
- table->allocation = new_allocation;
- }
- else
- {
- table->allocation = 4096;
- table->values = (void**)calloc(table->allocation, sizeof(void*));
+ va_list ap; va_start(ap, fmt);
+ char bfr[BCTEXTLEN]; vsnprintf(bfr, sizeof(bfr), fmt, ap);
+ va_end(ap);
+ DIR *dir = opendir(bfr);
+ if( !dir ) return;
+ struct dirent64 *dent;
+ while( --lines >= 0 && (dent = readdir64(dir)) ) {
+ const char *fn = dent->d_name;
+ fprintf(ofp, "%s", fn);
+ char path[BCTEXTLEN], link[BCTEXTLEN];
+ struct stat st;
+ snprintf(path, sizeof(path), "%s/%s", bfr, fn);
+ if( !stat(path,&st) ) {
+ int typ = 0;
+ if( S_ISREG(st.st_mode) ) typ = ' ';
+ else if( S_ISDIR(st.st_mode) ) typ = 'd';
+ else if( S_ISBLK(st.st_mode) ) typ = 'b';
+ else if( S_ISCHR(st.st_mode) ) typ = 'c';
+ else if( S_ISFIFO(st.st_mode) ) typ = 'f';
+ else if( S_ISLNK(st.st_mode) ) typ = 'l';
+ else if( S_ISSOCK(st.st_mode) ) typ = 's';
+ if( typ ) fprintf(ofp, "\t%c", typ);
+ fprintf(ofp, "\tsize %jd", st.st_size);
+ int len = readlink(path, link, sizeof(link)-1);
+ if( len > 0 ) {
+ link[len] = 0;
+ fprintf(ofp, "\t-> %s", link);
+ }
}
- }
-
- table->values[table->size++] = ptr;
- return ptr;
-}
-
-// Replace item in table pointed to by current_value and advance
-// current_value
-static void* overwrite_table(bc_table_t *table, void *ptr)
-{
- free(table->values[table->current_value]);
- table->values[table->current_value++] = ptr;
- if(table->current_value >= table->size) table->current_value = 0;
- return 0;
-}
-
-static void clear_table(bc_table_t *table, int delete_objects)
-{
- if(delete_objects)
- {
- for(int i = 0; i < table->size; i++)
- {
- free(table->values[i]);
+ snprintf(path, sizeof(path), "%sinfo/%s", bfr, fn);
+ FILE *fp = fopen(path,"r"); int64_t pos;
+ if( fp ) {
+ while( fgets(link, sizeof(link), fp) ) {
+ if( sscanf(link, "pos:%jd", &pos) == 1 ) {
+ fprintf(ofp, "\tpos: %jd", pos);
+ break;
+ }
+ }
+ fclose(fp);
}
+ fprintf(ofp, "\n");
}
- table->size = 0;
-}
-
-static void clear_table_entry(bc_table_t *table, int number, int delete_object)
-{
- if(delete_object) free(table->values[number]);
- for(int i = number; i < table->size - 1; i++)
- {
- table->values[i] = table->values[i + 1];
- }
- table->size--;
+ closedir(dir);
}
-// Table of functions currently running.
-static bc_table_t execution_table = { 0, 0, 0, 0 };
-
-// Table of locked positions
-static bc_table_t lock_table = { 0, 0, 0, 0 };
-
-// Table of buffers
-static bc_table_t memory_table = { 0, 0, 0, 0 };
-
-static bc_table_t temp_files = { 0, 0, 0, 0 };
-
// Can't use Mutex because it would be recursive
-static pthread_mutex_t *lock = 0;
static pthread_mutex_t *handler_lock = 0;
-// incase lock set after task ends
-static pthread_t last_lock_thread = 0;
-static const char *last_lock_title = 0;
-static const char *last_lock_location = 0;
-// Don't trace memory until this is true to avoid initialization
-static int trace_memory = 0;
static const char* signal_titles[] =
void BC_Signals::kill_subs()
{
// List /proc directory
- DIR *dirstream;
struct dirent64 *new_filename;
struct stat ostat;
- char path[BCTEXTLEN];
- char string[BCTEXTLEN];
-
- dirstream = opendir("/proc");
- if(!dirstream) return;
+ char path[BCTEXTLEN], string[BCTEXTLEN];
+ DIR *dirstream = opendir("/proc");
+ if( !dirstream ) return;
+ pid_t ppid = getpid();
- while( (new_filename = readdir64(dirstream)) != 0 )
- {
-// All digits are numbers
+ while( (new_filename = readdir64(dirstream)) != 0 ) {
char *ptr = new_filename->d_name;
- int got_alpha = 0;
- while(*ptr)
- {
- if(*ptr == '.' || isalpha(*ptr++))
- {
- got_alpha = 1;
- break;
- }
- }
-
- if(got_alpha) continue;
+ while( *ptr && *ptr != '.' && !isalpha(*ptr) ) ++ptr;
+// All digits are numbers
+ if( *ptr ) continue;
// Must be a directory
sprintf(path, "/proc/%s", new_filename->d_name);
- if(!stat(path, &ostat))
- {
- if(S_ISDIR(ostat.st_mode))
- {
-// Read process stat
- strcat(path, "/stat");
-//printf("kill_subs %d %s\n", __LINE__, path);
- FILE *fd = fopen(path, "r");
-
-// Must search forwards because the file is 0 length
- if(fd)
- {
- while(!feof(fd))
- {
- char c = fgetc(fd);
+ if( stat(path, &ostat) ) continue;
+ if( !S_ISDIR(ostat.st_mode) ) continue;
+ strcat(path, "/stat");
+ FILE *fd = fopen(path, "r");
+ if( !fd ) continue;
+ while( !feof(fd) && fgetc(fd)!=')' );
//printf("kill_subs %d %d\n", __LINE__, c);
- if(c == ')')
- {
-// Search for 2 spaces
- int spaces = 0;
- while(!feof(fd) && spaces < 2)
- {
- c = fgetc(fd);
- if(c == ' ')
- spaces++;
- }
-
+ for( int sp=2; !feof(fd) && sp>0; )
+ if( fgetc(fd) == ' ' ) --sp;
// Read in parent process
- ptr = string;
- while(!feof(fd))
- {
- *ptr = fgetc(fd);
- if(*ptr == ' ')
- {
- *ptr = 0;
- break;
- }
- ptr++;
- }
+ for( ptr=string; !feof(fd) && (*ptr=fgetc(fd))!=' '; ++ptr );
+ if( (*ptr=fgetc(fd)) == ' ' ) break;
+ *ptr = 0;
// printf("kill_subs %d process=%d getpid=%d parent_process=%d\n",
-// __LINE__,
-// atoi(new_filename->d_name),
-// getpid(),
-// atoi(string));
- int parent_process = atoi(string);
- int child_process = atoi(new_filename->d_name);
-
+// __LINE__, atoi(new_filename->d_name), getpid(), atoi(string));
+ int parent_process = atoi(string);
// Kill if we're the parent
- if(getpid() == parent_process)
- {
+ if( ppid == parent_process ) {
+ int child_process = atoi(new_filename->d_name);
//printf("kill_subs %d: process=%d\n", __LINE__, atoi(new_filename->d_name));
- kill(child_process, SIGKILL);
- }
- }
- }
-
- fclose(fd);
- }
- }
+ kill(child_process, SIGKILL);
}
+ fclose(fd);
}
}
signal(signum, SIG_DFL);
pthread_mutex_lock(handler_lock);
- if(signal_done)
- {
- pthread_mutex_unlock(handler_lock);
- exit(0);
- }
-
+ int done = signal_done;
signal_done = 1;
pthread_mutex_unlock(handler_lock);
-
+ if( done ) exit(0);
printf("signal_entry: got %s my pid=%d execution table size=%d:\n",
- signal_titles[signum],
- getpid(),
- execution_table.size);
+ signal_titles[signum], getpid(), execution_table.size);
BC_Signals::kill_subs();
- BC_Signals::dump_traces();
- BC_Signals::dump_locks();
- BC_Signals::dump_buffers();
- BC_Signals::delete_temps();
+ BC_Trace::dump_traces();
+ BC_Trace::dump_locks();
+ BC_Trace::dump_buffers();
+ BC_Trace::delete_temps();
// Call user defined signal handler
BC_Signals::global_signals->signal_handler(signum);
BC_Signals::BC_Signals()
{
}
-
-void BC_Signals::dump_traces(FILE *fp)
-{
-// Dump trace table
- if(execution_table.size)
- {
- for(int i = execution_table.current_value; i < execution_table.size; i++)
- fprintf(fp," %s\n", (char*)execution_table.values[i]);
- for(int i = 0; i < execution_table.current_value; i++)
- fprintf(fp," %s\n", (char*)execution_table.values[i]);
- }
-
-}
-
-void BC_Signals::dump_locks(FILE *fp)
-{
-// Dump lock table
-#ifdef TRACE_LOCKS
- fprintf(fp,"signal_entry: lock table size=%d\n", lock_table.size);
- for(int i = 0; i < lock_table.size; i++)
- {
- bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i];
- fprintf(fp," %p %s %s %p%s\n", table->ptr,
- table->title, table->location, (void*)table->tid,
- table->is_owner ? " *" : "");
- }
-#endif
-}
-
-void BC_Signals::dump_buffers(FILE *fp)
-{
-#ifdef TRACE_MEMORY
- pthread_mutex_lock(lock);
-// Dump buffer table
- fprintf(fp,"BC_Signals::dump_buffers: buffer table size=%d\n", memory_table.size);
- for(int i = 0; i < memory_table.size; i++)
- {
- bc_buffertrace_t *entry = (bc_buffertrace_t*)memory_table.values[i];
- fprintf(fp," %d %p %s\n", entry->size, entry->ptr, entry->location);
- }
- pthread_mutex_unlock(lock);
-#endif
-}
-
-void BC_Signals::delete_temps()
-{
- pthread_mutex_lock(lock);
- if(temp_files.size) printf("BC_Signals::delete_temps: deleting %d temp files\n", temp_files.size);
- for(int i = 0; i < temp_files.size; i++)
- {
- printf(" %s\n", (char*)temp_files.values[i]);
- remove((char*)temp_files.values[i]);
- }
- pthread_mutex_unlock(lock);
-}
-
-void BC_Signals::reset_locks()
+BC_Signals::~BC_Signals()
{
- pthread_mutex_unlock(lock);
-}
-
-void BC_Signals::set_temp(char *string)
-{
- char *new_string = strdup(string);
- append_table(&temp_files, new_string);
-}
-
-void BC_Signals::unset_temp(char *string)
-{
- for(int i = 0; i < temp_files.size; i++)
- {
- if(!strcmp((char*)temp_files.values[i], string))
- {
- clear_table_entry(&temp_files, i, 1);
- break;
- }
- }
+ BC_CModels::bcxfer_stop_slicers();
}
{
char string[1024];
XGetErrorText(event->display, event->error_code, string, 1024);
- fprintf(stderr, "BC_Signals::x_error_handler: error_code=%d opcode=%d,%d %s\n",
- event->error_code, event->request_code, event->minor_code, string);
+ fprintf(stderr, "BC_Signals::x_error_handler: error_code=%d opcode=%d,%d id=0x%jx %s\n",
+ event->error_code, event->request_code, event->minor_code,
+ (int64_t)event->resourceid, string);
return 0;
}
-void BC_Signals::initialize()
+void BC_Signals::initialize(const char *trap_path)
{
BC_Signals::global_signals = this;
- lock = (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t));
+ BC_Trace::global_trace = this;
+ set_trap_path(trap_path);
handler_lock = (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t));
- pthread_mutex_init(lock, 0);
pthread_mutex_init(handler_lock, 0);
old_err_handler = XSetErrorHandler(x_error_handler);
initialize2();
void BC_Signals::terminate()
{
BC_Signals::global_signals = 0;
+ BC_Trace::global_trace = 0;
uncatch_segv(); uncatch_intr();
signal(SIGHUP, SIG_DFL);
signal(SIGINT, SIG_DFL);
XSetErrorHandler(old_err_handler);
}
-// callable from debugger
-extern "C"
-void dump()
-{
- BC_Signals::dump_traces();
- BC_Signals::dump_locks();
- BC_Signals::dump_buffers();
-}
-
// kill SIGUSR2
void BC_Signals::signal_dump(int signum)
{
return signal_titles[number];
}
-#define TOTAL_TRACES 16
-
-void BC_Signals::new_trace(const char *text)
-{
- if(!global_signals) return;
- pthread_mutex_lock(lock);
-
-// Wrap around
- if(execution_table.size >= TOTAL_TRACES)
- {
- overwrite_table(&execution_table, strdup(text));
-// clear_table(&execution_table, 1);
- }
- else
- {
- append_table(&execution_table, strdup(text));
- }
- pthread_mutex_unlock(lock);
-}
-
-void BC_Signals::new_trace(const char *file, const char *function, int line)
-{
- char string[BCTEXTLEN];
- snprintf(string, BCTEXTLEN, "%s: %s: %d", file, function, line);
- new_trace(string);
-}
-
-void BC_Signals::delete_traces()
-{
- if(!global_signals) return;
- pthread_mutex_lock(lock);
- clear_table(&execution_table, 0);
- pthread_mutex_unlock(lock);
-}
-
-// no canceling with lock held
-void BC_Signals::lock_locks(const char *s)
-{
- pthread_mutex_lock(lock);
- last_lock_thread = pthread_self();
- last_lock_title = s;
- last_lock_location = 0;
-}
-
-void BC_Signals::unlock_locks()
-{
- pthread_mutex_unlock(lock);
-}
-
-#define TOTAL_LOCKS 256
-
-int BC_Signals::set_lock(void *ptr,
- const char *title,
- const char *location)
-{
- if(!global_signals) return 0;
- bc_locktrace_t *table = 0;
- int id_return = 0;
-
- pthread_mutex_lock(lock);
- last_lock_thread = pthread_self();
- last_lock_title = title;
- last_lock_location = location;
- if(lock_table.size >= TOTAL_LOCKS)
- clear_table(&lock_table, 0);
-
-// Put new lock entry
- table = new_bc_locktrace(ptr, title, location);
- append_table(&lock_table, table);
- id_return = table->id;
-
- pthread_mutex_unlock(lock);
- return id_return;
-}
-
-void BC_Signals::set_lock2(int table_id)
-{
- if(!global_signals) return;
-
- bc_locktrace_t *table = 0;
- pthread_mutex_lock(lock);
- for(int i = lock_table.size - 1; i >= 0; i--)
- {
- table = (bc_locktrace_t*)lock_table.values[i];
-// Got it. Hasn't been unlocked/deleted yet.
- if(table->id == table_id)
- {
- table->is_owner = 1;
- table->tid = pthread_self();
- pthread_mutex_unlock(lock);
- return;
- }
- }
- pthread_mutex_unlock(lock);
-}
-
-void BC_Signals::unset_lock2(int table_id)
-{
- if(!global_signals) return;
-
- bc_locktrace_t *table = 0;
- pthread_mutex_lock(lock);
- for(int i = lock_table.size - 1; i >= 0; i--)
- {
- table = (bc_locktrace_t*)lock_table.values[i];
- if(table->id == table_id)
- {
- clear_table_entry(&lock_table, i, 1);
- break;
- }
- }
- pthread_mutex_unlock(lock);
-}
-
-void BC_Signals::unset_lock(void *ptr)
-{
- if(!global_signals) return;
-
- bc_locktrace_t *table = 0;
- pthread_mutex_lock(lock);
-
-// Take off currently held entry
- for(int i = 0; i < lock_table.size; i++)
- {
- table = (bc_locktrace_t*)lock_table.values[i];
- if(table->ptr == ptr)
- {
- if(table->is_owner)
- {
- clear_table_entry(&lock_table, i, 1);
- break;
- }
- }
- }
-
- pthread_mutex_unlock(lock);
-}
-
-
-void BC_Signals::unset_all_locks(void *ptr)
-{
- if(!global_signals) return;
- pthread_mutex_lock(lock);
-// Take off previous lock entry
- for(int i = 0; i < lock_table.size; )
- {
- bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i];
- if(table->ptr == ptr)
- {
- clear_table_entry(&lock_table, i, 1);
- continue;
- }
- ++i;
- }
- pthread_mutex_unlock(lock);
-}
-
-void BC_Signals::clear_locks_tid(pthread_t tid)
-{
- if(!global_signals) return;
- pthread_mutex_lock(lock);
-// Take off previous lock entry
- for(int i = 0; i < lock_table.size; )
- {
- bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i];
- if(table->tid == tid)
- {
- clear_table_entry(&lock_table, i, 1);
- continue;
- }
- ++i;
- }
- pthread_mutex_unlock(lock);
-}
-
-
-void BC_Signals::enable_memory()
-{
- trace_memory = 1;
-}
-
-void BC_Signals::disable_memory()
-{
- trace_memory = 0;
-}
-
-
-void BC_Signals::set_buffer(int size, void *ptr, const char* location)
-{
- if(!global_signals) return;
- if(!trace_memory) return;
-
-//printf("BC_Signals::set_buffer %p %s\n", ptr, location);
- pthread_mutex_lock(lock);
- append_table(&memory_table, new_bc_buffertrace(size, ptr, location));
- pthread_mutex_unlock(lock);
-}
-
-int BC_Signals::unset_buffer(void *ptr)
-{
- if(!global_signals) return 0;
- if(!trace_memory) return 0;
-
- int ret = 1;
- pthread_mutex_lock(lock);
- for(int i = 0; i < memory_table.size; i++)
- {
- if(((bc_buffertrace_t*)memory_table.values[i])->ptr == ptr)
- {
-//printf("BC_Signals::unset_buffer %p\n", ptr);
- clear_table_entry(&memory_table, i, 1);
- ret = 0;
- break;
- }
- }
-
- pthread_mutex_unlock(lock);
-// fprintf(stderr, "BC_Signals::unset_buffer buffer %p not found.\n", ptr);
- return ret;
-}
-
#include <ucontext.h>
#include <sys/wait.h>
signal(SIGINT, SIG_DFL);
// gotta be root, or the dump is worthless
int uid = getuid();
- if( uid != 0 ) return;
+// it is not necessary to be root if ptrace is allowed via:
+// echo 0 > /proc/sys/kernel/yama/ptrace_scope (usually set to 1)
+// if( uid != 0 ) return;
ucontext_t *uc = (ucontext_t *)sc;
int pid = getpid(), tid = gettid();
struct sigcontext *c = (struct sigcontext *)&uc->uc_mcontext;
+ uint8_t *ip = (uint8_t *)c->IP;
fprintf(stderr,"** %s at %p in pid %d, tid %d\n",
n==SIGSEGV? "segv" : n==SIGINT? "intr" : "trap",
- (void*)c->IP, pid, tid);
+ (void*)ip, pid, tid);
FILE *fp = 0;
char fn[PATH_MAX];
if( BC_Signals::trap_path ) {
fprintf(fp," by %d:%d %s(%s)\n",
pw->pw_uid, pw->pw_gid, pw->pw_name, pw->pw_gecos);
}
- fprintf(fp,"\nTHREADS:\n"); Thread::dump_threads(fp);
- fprintf(fp,"\nTRACES:\n"); BC_Signals::dump_traces(fp);
- fprintf(fp,"\nLOCKS:\n"); BC_Signals::dump_locks(fp);
- fprintf(fp,"\nBUFFERS:\n"); BC_Signals::dump_buffers(fp);
+ fprintf(fp,"\nCPUS: %d\n", BC_Resources::get_machine_cpus());
+ fprintf(fp,"\nCPUINFO:\n"); bc_copy_textfile(32, fp,"/proc/cpuinfo");
+ fprintf(fp,"\nTHREADS:\n"); BC_Trace::dump_threads(fp);
+ fprintf(fp,"\nTRACES:\n"); BC_Trace::dump_traces(fp);
+ fprintf(fp,"\nLOCKS:\n"); BC_Trace::dump_locks(fp);
+ fprintf(fp,"\nBUFFERS:\n"); BC_Trace::dump_buffers(fp);
+ fprintf(fp,"\nSHMMEM:\n"); BC_Trace::dump_shm_stats(fp);
if( BC_Signals::trap_hook ) {
fprintf(fp,"\nMAIN HOOK:\n");
BC_Signals::trap_hook(fp, BC_Signals::trap_data);
}
- fprintf(fp,"\nVERSION:\n"); bc_copy_textfile(fp,"/proc/version");
- fprintf(fp,"\nMEMINFO:\n"); bc_copy_textfile(fp,"/proc/meminfo");
- fprintf(fp,"\nMAPS:\n"); bc_copy_textfile(fp,"/proc/%d/maps",pid);
+ fprintf(fp,"\nVERSION:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/version");
+ fprintf(fp,"\nMEMINFO:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/meminfo");
+ fprintf(fp,"\nSTATUS:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/%d/status",pid);
+ fprintf(fp,"\nFD:\n"); bc_list_openfiles(INT_MAX, fp,"/proc/%d/fd", pid);
+ fprintf(fp,"\nMAPS:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/%d/maps",pid);
+ char proc_mem[64];
+ if( tid > 0 && tid != pid )
+ sprintf(proc_mem,"/proc/%d/task/%d/mem",pid,tid);
+ else
+ sprintf(proc_mem,"/proc/%d/mem",pid);
+ int pfd = open(proc_mem,O_RDONLY);
+ if( pfd >= 0 ) {
+ fprintf(fp,"\nCODE:\n");
+ for( int i=-32; i<32; ) {
+ uint8_t v; void *vp = (void *)(ip + i);
+ if( !(i & 7) ) fprintf(fp,"%p: ", vp);
+ if( pread(pfd,&v,sizeof(v),(off_t)vp) != sizeof(v) ) break;
+ fprintf(fp,"%c%02x", !i ? '>' : ' ', v);
+ if( !(++i & 7) ) fprintf(fp,"\n");
+ }
+ fprintf(fp,"\n");
+ close(pfd);
+ }
+ else
+ fprintf(fp,"err opening: %s, %m\n", proc_mem);
+
fprintf(fp,"\n\n");
if( fp != stdout ) fclose(fp);
char cmd[1024], *cp = cmd;
execvp(argv[0], &argv[0]);
}
-
-
-
-
-#ifdef TRACE_MEMORY
-
-// void* operator new(size_t size)
-// {
-// //printf("new 1 %d\n", size);
-// void *result = malloc(size);
-// BUFFER(size, result, "new");
-// //printf("new 2 %d\n", size);
-// return result;
-// }
-//
-// void* operator new[](size_t size)
-// {
-// //printf("new [] 1 %d\n", size);
-// void *result = malloc(size);
-// BUFFER(size, result, "new []");
-// //printf("new [] 2 %d\n", size);
-// return result;
-// }
-//
-// void operator delete(void *ptr)
-// {
-// //printf("delete 1 %p\n", ptr);
-// UNBUFFER(ptr);
-// //printf("delete 2 %p\n", ptr);
-// free(ptr);
-// }
-//
-// void operator delete[](void *ptr)
-// {
-// //printf("delete [] 1 %p\n", ptr);
-// UNBUFFER(ptr);
-// free(ptr);
-// //printf("delete [] 2 %p\n", ptr);
-// }
-
-
-#endif