main.c

来自「早期freebsd实现」· C语言 代码 · 共 509 行

C
509
字号
/* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1983 The Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)main.c	5.7 (Berkeley) 6/1/90";#endif /* not lint *//* * Debugger main routine. */#include "defs.h"#include <setjmp.h>#include <signal.h>#include <errno.h>#include "main.h"#include "tree.h"#include "eval.h"#include "debug.h"#include "symbols.h"#include "scanner.h"#include "keywords.h"#include "process.h"#include "runtime.h"#include "source.h"#include "object.h"#include "mappings.h"#include "coredump.h"#include "pathnames.h"#ifndef public#define isterm(file)	(interactive or isatty(fileno(file)))#ifdef IRIS#   include <termio.h>    typedef struct termio Ttyinfo;#else#   include <sgtty.h>#   include <fcntl.h>    typedef struct {	struct sgttyb sg;		/* standard sgttyb structure */	struct tchars tc;		/* terminal characters */	struct ltchars ltc;		/* local special characters */	integer ldisc;			/* line discipline */	integer local;			/* TIOCLGET */	integer fcflags;		/* fcntl(2) F_GETFL, F_SETFL */    } Ttyinfo;#endif#endifpublic boolean coredump;		/* true if using a core dump */public boolean runfirst;		/* run program immediately */public boolean interactive;		/* standard input IS a terminal */public boolean lexdebug;		/* trace scanner return values */public boolean tracebpts;		/* trace create/delete breakpoints */public boolean traceexec;		/* trace execution */public boolean tracesyms;		/* print symbols are they are read */public boolean traceblocks;		/* trace blocks while reading symbols */public boolean vaddrs;			/* map addresses through page tables */public boolean quiet;			/* don't print heading */public boolean autostrip;		/* strip C++ prefixes */public File corefile;			/* File id of core dump */public integer versionNumber = 4;#define FIRST_TIME 0			/* initial value setjmp returns */private Boolean initdone = false;	/* true if initialization done */private jmp_buf env;			/* setjmp/longjmp data */private char outbuf[BUFSIZ];		/* standard output buffer */private char namebuf[512];		/* possible name of object file */private Ttyinfo ttyinfo;private String corename;		/* name of core file */private catchintr();private char **scanargs();/* * Main program. */main(argc, argv)int argc;String argv[];{    extern integer versionNumber;    char **scanargs();    if (!(cmdname = rindex(*argv, '/')))	cmdname = *argv;    else	++cmdname;    catcherrs();    onsyserr(EINTR, nil);    onsyserr(EADDRINUSE, nil);    onsyserr(ENXIO, nil);    setbuf(stdout, outbuf);    argv = scanargs(argc, argv);    if (not runfirst and not quiet) {	printheading();    }    openfiles();    language_init();    symbols_init();    process_init();    optab_init();    if (runfirst) {	if (setjmp(env) == FIRST_TIME) {	    arginit();	    while (*argv)		newarg(*argv++);	    run();	    /* NOTREACHED */	} else {	    runfirst = false;	}    } else {	init();    }    if (setjmp(env) != FIRST_TIME) {	restoretty(stdout, &ttyinfo);    }    signal(SIGINT, catchintr);    yyparse();    putchar('\n');    quit(0);}public printheading (){    extern String date;    printf("dbx version 3.%d of %s.\nType 'help' for help.\n",	versionNumber, date    );    fflush(stdout);}/* * Initialize the world, including setting initial input file * if the file exists. */public init(){    File f;    String home;    char buf[100];    extern String getenv();    savetty(stdout, &ttyinfo);    enterkeywords();    scanner_init();    if (not coredump and not runfirst) {	start(nil, nil, nil);    }    printf("reading symbolic information ...");    fflush(stdout);    readobj(objname);    printf("\n");    fflush(stdout);    if (coredump) {	printf("[using memory image in %s]\n", corename);	if (vaddrs) {	    coredump_getkerinfo();	}	getsrcpos();	setcurfunc(whatblock(pc));    } else {	setcurfunc(program);    }    bpinit();    f = fopen(initfile, "r");    if (f != nil) {	fclose(f);	setinput(initfile);    } else {	home = getenv("HOME");	if (home != nil) {	    sprintf(buf, "%s/%s", home, initfile);	    f = fopen(buf, "r");	    if (f != nil) {		fclose(f);		setinput(strdup(buf));	    }	}    }    initdone = true;}/* * Re-initialize the world, first de-allocating all storage. * This is necessary when the symbol information must be re-read * from the object file when it has changed. * * Before "forgetting" things, we save the current tracing/breakpoint * information to a temp file.  Then after re-creating the world, * we read the temp file as commands.  This isn't always the right thing; * if a procedure that was being traced is deleted, an error message * will be generated. * * If the argument vector is not nil, then this is re-initialize is being * done in preparation for running the program.  Since we want to process * the commands in the temp file before running the program, we add the * run command at the end of the temp file.  In this case, reinit longjmps * back to parsing rather than returning. */public reinit(argv, infile, outfile)String *argv;String infile;String outfile;{    register Integer i;    String tmpfile;    extern String mktemp();    tmpfile = mktemp(_PATH_TMP);    setout(tmpfile);    status();    alias(nil, nil, nil);    if (argv != nil) {	printf("run");	for (i = 1; argv[i] != nil; i++) {	    printf(" %s", argv[i]);	}	if (infile != nil) {	    printf(" < %s", infile);	}	if (outfile != nil) {	    printf(" > %s", outfile);	}	putchar('\n');    }    unsetout();    bpfree();    objfree();    symbols_init();    process_init();    enterkeywords();    scanner_init();    readobj(objname);    bpinit();    fflush(stdout);    setinput(tmpfile);    unlink(tmpfile);    if (argv != nil) {	longjmp(env, 1);	/* NOTREACHED */    }}/* * After a non-fatal error we skip the rest of the current input line, and * jump back to command parsing. */public erecover(){    if (initdone) {	gobble();	longjmp(env, 1);    }}/* * This routine is called when an interrupt occurs. */private catchintr(){    if (isredirected()) {	fflush(stdout);	unsetout();    }    putchar('\n');    longjmp(env, 1);}/* * Scan the argument list. */private char **scanargs (argc, argv)int argc;String argv[];{    extern char *optarg;    extern integer optind;    integer ch;    runfirst = false;    interactive = false;    lexdebug = false;    tracebpts = false;    traceexec = false;    tracesyms = false;    traceblocks = false;    vaddrs = false;    quiet = false;    autostrip = true;    corefile = nil;    coredump = true;    sourcepath = list_alloc();    list_append(list_item("."), nil, sourcepath);    while ((ch = getopt(argc, argv, "I:abc:eiklnqrs")) != EOF)    switch((char)ch) {	case 'I':		list_append(list_item(optarg), nil, sourcepath);		break;	case 'a':		autostrip = false;		break;	case 'b':		tracebpts = true;		break;	case 'c':		initfile = optarg;		break;	case 'e':		traceexec = true;		break;	case 'i':		interactive = true;		break;	case 'k':		vaddrs = true;		break;	case 'l':#ifdef LEXDEBUG		lexdebug = true;#else		fatal("\"-l\" only applicable when compiled with LEXDEBUG");#endif		break;	case 'n':		traceblocks = true;		break;	case 'q':		quiet = true;		break;	case 'r':	/* run program before accepting commands */		runfirst = true;		coredump = false;		break;	case 's':		tracesyms = true;		break;	case '?':	default:		fatal("unknown option");    }    argv += optind;    if (*argv) {	objname = *argv;	if (*++argv && coredump) {		corename = *argv;		corefile = fopen(*argv, "r");		if (corefile == nil)			coredump = false;		++argv;	}    }    if (*argv and not runfirst) {	fatal("extraneous argument %s", *argv);    }    return argv;}private openfiles (){    File f;    char *tmp;    if (objname == nil and isatty(0)) {	printf("enter object file name (default is `%s'): ", objname);	fflush(stdout);	gets(namebuf);	if (namebuf[0] != '\0') {	    objname = namebuf;	}    }    f = fopen(objname, "r");    if (f == nil) {	fatal("can't read %s", objname);    } else {	fclose(f);    }    if (rindex(objname, '/') != nil) {	tmp = strdup(objname);	*(rindex(tmp, '/')) = '\0';	list_append(list_item(tmp), nil, sourcepath);    }    if (coredump and corefile == nil) {	if (vaddrs) {	    corename = _PATH_MEM;	    corefile = fopen(corename, "r");	    if (corefile == nil) {		panic("can't open %s", _PATH_MEM);	    }	} else {	    corename = "core";	    corefile = fopen(corename, "r");	    if (corefile == nil) {		coredump = false;	    }	}    }}/* * Save/restore the state of a tty. */public savetty(f, t)File f;Ttyinfo *t;{#   ifdef IRIS	ioctl(fileno(f), TCGETA, t);#   else	ioctl(fileno(f), TIOCGETP, &(t->sg));	ioctl(fileno(f), TIOCGETC, &(t->tc));	ioctl(fileno(f), TIOCGLTC, &(t->ltc));	ioctl(fileno(f), TIOCGETD, &(t->ldisc));	ioctl(fileno(f), TIOCLGET, &(t->local));	t->fcflags = fcntl(fileno(f), F_GETFL, 0);	if ((t->fcflags&FASYNC) != 0) {	    /* fprintf(stderr, "[async i/o found set -- reset]\n"); */	    t->fcflags &= ~FASYNC;	}#   endif}public restoretty(f, t)File f;Ttyinfo *t;{#   ifdef IRIS	ioctl(fileno(f), TCSETA, t);#   else	ioctl(fileno(f), TIOCSETN, &(t->sg));	ioctl(fileno(f), TIOCSETC, &(t->tc));	ioctl(fileno(f), TIOCSLTC, &(t->ltc));	ioctl(fileno(f), TIOCSETD, &(t->ldisc));	ioctl(fileno(f), TIOCLSET, &(t->local));	if ((t->fcflags&FASYNC) != 0) {	    /* fprintf(stderr, "[async i/o not set]\n"); */	    t->fcflags &= ~FASYNC;	}	(void) fcntl(fileno(f), F_SETFL, t->fcflags);#   endif}/* * Exit gracefully. */public quit(r)Integer r;{    pterm(process);    exit(r);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?