File:  [Research Unix] / researchv9 / jtools / src / pi / hostproc.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include "univ.h"
#include "process.pri"
#include "sigmask.h"
#include "hostcore.h"
#include "expr.pub"
#include "master.pub"
#include "bpts.pri"
#include "frame.pri"
#include "memory.pub"
#include "symtab.pub"
#include "symbol.h"
#include "srcdir.h"
#include "asm.pub"
#include <CC/stdio.h>
SRCFILE("hostproc.c")

int access(char*,int);
int kill(int,int);

static char *pathexpand(char *f)
{
	static char file[128];
	extern char *PATH;
	register char *pa, *p;

	if (*f != '/' && strncmp(f, "./", 2) && strncmp(f, "../", 3) && 
	    (pa=PATH)!=0){
		while(*pa){
			for(p=file; *pa && *pa!=':'; p++,pa++)
				*p= *pa;
			if(p!=file)
				*p++='/';
			if(*pa)
				pa++;
			(void)strcpy(p, f);
			if (access(file, 5) != -1)
				return file;
		}
	}
	if (access(f, 5) != -1 )
		return f;
	return 0;
}

void HostProcess::takeoverstopped()
{
	if( pad ){
		openstopped();
		insert(ERRORKEY, "take over: already open");
		return;
	}
	Pick( "take over", (Action)&HostProcess::substitute, (long) this );
}

void HostProcess::reopendump()
{
	char *error;

	insert(ERRORKEY, 0);
	if( error = core->reopen(procpath, stabpath) ){
		insert(ERRORKEY, error);
		return;
	}
	docycle();
}

void HostProcess::substitute(HostProcess *t)
{
	char *error, *oldprocpath, *oldstabpath, *oldcomment;

	insert(ERRORKEY, 0);
	if( !core ){
		insert(ERRORKEY, "that ought to work - but it doesn't");
		return;
	}
	if( !core->online() ){
		insert(ERRORKEY, "cannot take over a coredump");
		return;
	}
	_bpts->lift();
	if( error = core->reopen(t->procpath, t->stabpath) ){
		_bpts->lay();
		insert(ERRORKEY, error);
		return;
	}
					/*	t->kill();	*/
	oldprocpath = procpath;
	oldstabpath = stabpath;
	oldcomment = comment;
	procpath = t->procpath;
	stabpath = t->stabpath;
	comment = t->comment;
	master->makeproc( oldprocpath, oldstabpath, oldcomment );
	master->insert(t);
	master->insert(this);
	banner();
	if( _asm ) _asm->banner();
	if( _bpts ) _bpts->banner();
	if( memory ) memory->banner();
	if( globals ) globals->banner();
	if( sigmsk ){
		sigmsk->banner();
		sigmsk->updatecore();
	}
	if( srcdir ) srcdir->banner();
	core->symtab()->banner();
	pad->clear();
	_bpts->lay();
	docycle();
}

int HostProcess::accept( Action a )
{
	return a == (Action)&HostProcess::substitute;
}

void HostProcess::imprint()
{
	char *parentpath = sf("%s%d", slashname(procpath), hostcore()->ppid() );
	insert(ERRORKEY, "parent=%s", parentpath);
	Process *p = master->search(parentpath);
	if( !p ){
		insert(ERRORKEY, "parent (%d) not opened", hostcore()->ppid());
		return;
	}
	_bpts->liftparents(p->_bpts);
}

void HostProcess::userclose()
{
	if( sigmsk ){
		sigmsk->hostclose();
		delete sigmsk;
		sigmsk = 0;
	}
	Process::userclose();
}

int HostProcess::openstopped(long ischild)
{
	Menu m, s;
	char *error;

	Process::openpad();
	if( core ) return 1;
	insert(ERRORKEY, "Checking process and symbol table...");
	core = (Core*) new HostCore(this, master);
	if( error = core->open() ){
		delete core;
		core = 0;
		if( ischild )
			m.last( "open child", (Action)&HostProcess::open, 1 );
		else
			m.last( "open process", (Action)&HostProcess::open, 0 );
		pad->menu( m );
		insert(ERRORKEY, error);
		return 0;
	}
	insert(ERRORKEY, core->symtab()->warn());
	globals = new Globals(core);
	_asm = core->newAsm();
	if( core->online() ){
		m.last( "stop", (Action)&HostProcess::stop );
		m.last( "run",  (Action)&Process::go  );
	}
	m.last( "src text",  (Action)&Process::srcfiles    );	/* should check */
	m.last( "Globals",   (Action)&Process::openglobals );
	m.last( "RawMemory", (Action)&Process::openmemory  );
	s.last( "Assembler", (Action)&Process::openasm     );
	s.last( "User Types",(Action)&Process::opentypes   );
	if( core->online() ){
		s.last("Journal", (Action)&Process::openjournal);
		s.last("Signals", (Action)&HostProcess::opensigmask);
		s.last("Bpt List", (Action)&HostProcess::openbpts);
		_bpts = new Bpts(core);
		_bpts->lay();
		if( ischild ) imprint();
		sigmsk = new SigMask(hostcore());
		m.last("kill?",   (Action)&HostProcess::destroy     );
	}
	m.last(s.index("more"));
	pad->menu(m);
	pad->makecurrent();
	docycle();
	return 1;
}

void HostProcess::opensigmask()
{
	if( sigmsk ) sigmsk->open();
}

void HostProcess::destroy()
{
	IF_LIVE( !core->online() ) return;
	insert(ERRORKEY, core->destroy());
	docycle();
}

void HostProcess::stop()
{
	IF_LIVE( !core->online() ) return;
	if( !(sigmsk->mask&sigmsk->bit(SIGSTOP)) ) sigmsk->setsig(SIGSTOP);
	Process::stop();
}

Index HostProcess::carte()
{
	Menu m;
	if( !strcmp(procpath,"!") ){
		m.last( "hang & open proc", (Action)&HostProcess::hangopen );
		m.last( "hang & take over", (Action)&HostProcess::hangtakeover );
	} else if( !strcmp(basename(procpath), "core") )
		m.last( "open coredump",(Action)&HostProcess::openstopped );
	else {
		m.last( "open process",  (Action)&HostProcess::open, 0 );
		m.last( "take over",    (Action)&HostProcess::takeover );
		m.last( "open child", (Action)&HostProcess::open, 1 );
	}
	return m.index();
}

void HostProcess::hang()
{
	char program[128];
	char *argv[10];
	
	char *from = stabpath;
	char *to = argv[0] = program;
	int i = 1;
	for(;;) {
		while(*from && *from != ' ')
			*to++ = *from++;
		*to++ = 0;
		if (*from == 0) {
			argv[i] = 0;
			break;
		} else {
			while (*++from == ' ')
				;
			if (*from)
				argv[i++] = to;
		}
	}
	char *ssave = stabpath;
	stabpath  = sf("%s", argv[0]);
	int pid = ::fork();
	if( !pid ){
		int fd;
		for( fd = 0; fd < _NFILE; ++fd ) ::close(fd);
		::open("/dev/null", 2);
		::dup2(0, 1);
		::dup2(0, 2);
		::setpgrp(0, ::getpid());
                ::ptrace(PTRACE_TRACEME, 0, 0, 0, 0);
                ::execvp(argv[0], argv);
		::exit(0);
	}		
	procpath = sf("%d", pid);
	master->makeproc("!", ssave);
	master->insert(this);
}

void HostProcess::hangopen()
{
	hang();
	openstopped();
}

void HostProcess::hangtakeover()
{
	hang();
	takeoverstopped();
}

void HostProcess::open(long ischild)
{
	char *error;
	int pid = 0;

	if( core )
		return;
	if (!stabpath) {
		char *nstab;
		char file[80];
		sscanf(comment, " %*s %*s %*s %s", file);
		if ((nstab = pathexpand(file)) == 0) {
			error = "Can't find symbol table file";
			goto err;
		}
		stabpath = sf("%s", nstab);
		comment = 0;
		master->insert(this);
	}
	sscanf(procpath, "%d", &pid);
	::kill(pid, SIGCONT);
	if (::ptrace(PTRACE_ATTACH, pid, 0, 0, 0)) {
		error = "Can't attach to process";
		goto err;
	}
	openstopped(ischild);
	return;
err:
	Process::openpad();
	insert(ERRORKEY, error);
	return;
	
}

void HostProcess::takeover()
{
	if (!stabpath) {
		char *nstab;
		char file[80];
		sscanf(comment, " %*s %*s %*s %s", file);
		if ((nstab = pathexpand(file)) == 0)
			return;
		stabpath = sf("%s", nstab);
		comment = 0;
		master->insert(this);
	}
	int pid = 0;
	sscanf(procpath, "%d", &pid);
	::kill(pid, SIGCONT);
	if (::ptrace(PTRACE_ATTACH, pid, 0, 0, 0))
		return;
	takeoverstopped();
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.