⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#include <bstring.h>#include <sys/signal.h>#include "gdb_interface.h"#include "mips_gdb.h"#include "simmisc.h"#include "embra.h"#include "debug.h"#include "clock.h"#include "main_run.h"#include "qc.h"#include "driver.h"#include "mem_control.h"#include "tcl_init.h"#include "tc.h"#include "cp0.h"#include "machine_params.h"/* Known Bugs: If you enter debugger when processes are in promslave loop *//* then you won't restart after.  */#define DEBUG 1#define BREAKPOINT 0x1#define SINGLESTEP 0x2#define SIGNAL 0x4#define INCR_PC 0x8#define FLUSH_TC 0x10#define SIDE_EFFECT 0x20#define SIGNAL_USR 0x2static struct EmbraDebug {   uint statusCode;   int ignoreNextOne;   int processingAnn;   int processingGDB;   SimTime lastDebugCycle[SIM_MAXCPUS];} embraDebug;/* ******************************************************** * EmbraSideEffect is called whenever a change in the machine * state (registers, not memory) occured during a callout.  * ********************************************************/void EmbraDebugInit(void){   int i;   embraDebug.statusCode = 0;   embraDebug.processingAnn = 0;   embraDebug.processingGDB = 0;   for (i=0;i<TOTAL_CPUS;i++) {       embraDebug.lastDebugCycle[i] = 0;   }}void EmbraSideEffect(void) {   if (embraDebug.processingAnn) {       embraDebug.statusCode |= SIDE_EFFECT;   }}void EmbraDebug( int cpuNum ){   int incrpc = embraDebug.statusCode & INCR_PC;      ASSERT( embra.sequential);   Simdebug_run(((embraDebug.statusCode & BREAKPOINT) ?                        SIGTRAP : SIGUSR2 ),                      cpuNum);   if (embraDebug.processingAnn ) {       /*       * finish the annotation first, then       * check for side-effects,...       */      return;   }   if (embraDebug.processingGDB) {       FlushTCIfNecessary(cpuNum);      if( incrpc ) {         EMP[cpuNum].PC += INST_SIZE;      }       ASSERT( (EMP[cpuNum].PC & 0x3) == 0 );      embraDebug.statusCode &= ~SIDE_EFFECT;      embraDebug.processingGDB = 0;      ReenterTC( &EMP[cpuNum] );      /* NOT REACHED */      return;   }             }void FlushTCIfNecessary(int cpuNum){   if( embraDebug.statusCode & FLUSH_TC ) {      /*        *this bit might get set in Simdebug_run        */      /* The following call does not work for       * MPinMP.  However, MPinUP ignores the       * cpuNum argument so it is fine.       *       * Problem is that debugger could have modified       * stuff that is in any cpu, so we need to       * flush stuff across the board.       */      Clear_Translation_State( TCFLUSH_ALL);      embraDebug.statusCode &=~FLUSH_TC;   }}int EmbraAnnType(void){   return embraDebug.processingAnn;}/* ************************************************************** * Embra_Handle_Debug_Signal *  * Called through CPUVec in the case of a debug annotation * and in the case of a SIGUSR1 * **************************************************************/void Embra_Handle_Debug_Signal( int cpuid, int sigusr ){  /*   * Handle the debugging or the signal synchronously   * However, we need to make sure that time has advanced,   * else, we will go into an infinite loop.    * Annotations that are on the same pc/mem location will   * be executed twice, with the exception of the debugging   * interaction (that ocurs once).    *    * This is required since we need to do a ReenterTC after   * the debugging interaction.    */   /* Check this value when we drop into debugger, it allows us to set the embraDebug.statusCode */   int cpu = (cpuid<0?CPUVec.CurrentCpuNum():cpuid);   ASSERT( cpu >= 0 && cpu < TOTAL_CPUS);   if (sigusr) {      embraDebug.statusCode = SIGNAL_USR;   } else {       /*       * process the debugging requests immediately       */      EmbraDebug(cpu);   }}/* This gets called from a kernel breakpoint */void Embra_SimosKernDebugBreak( int cpuNum ){   ASSERT (curEmp->myNum == cpuNum);   CPUWarning("DEBUGGER at %#x\n",EMP[cpuNum].PC);   embraDebug.statusCode = 0;   embraDebug.statusCode |= BREAKPOINT;   embraDebug.statusCode |= INCR_PC;   /* Kernel breakpoints are stepped over */   embraDebug.processingGDB = 1;   EmbraDebug(cpuNum);}/*  * this gets from a breakpoint too. Used to step.  */void Embra_SimosDebugBreak( int cpuNum ){   ASSERT (curEmp->myNum == cpuNum);   CPUWarning("DEBUG: Debug break\n");   if( embraDebug.lastDebugCycle[cpuNum]== EmbraCpuCycleCount( cpuNum ) ) {      /* prevent infinite loop        * This is our way of stepping over the code that calls the annotation       * by disabling it the next time around.       * Catch: any other annotations installed at the same PC        * will be called twice.       */      CPUWarning("Embra_SimosDebugBreak: skip \n");      return;   }   embraDebug.lastDebugCycle[cpuNum] = EmbraCpuCycleCount( cpuNum );   embraDebug.statusCode = 0;   embraDebug.statusCode |= BREAKPOINT;   embraDebug.processingGDB = 1;   EmbraDebug(cpuNum);}/* No one returns from this procedure *//* We leave via the execption path *//* This insures that if we wrote registers, our register allocaiton in *//* translation won't break *//* ***************************************************************** * EmbraPollSigUsr.  * the last thing we want to do is to interpret Tcl scripts on the  * signal stack. Called from the periodic callout  * *****************************************************************/void EmbraPollSigUsr( int cpuNum ){      if (embraDebug.statusCode & SIGNAL_USR) {      embraDebug.statusCode &= ~SIGNAL_USR;      AnnExec(AnnFind("simos", "sigusr"));   }}/* ************************************************************** * EmbraAnnExec *  * returns unless the annotation has a side-effect on the machine * state. *  * XXX Known limitiation: if the tcl script has side-effects and * the PC is in a delay slot, we are hosed!!! (for now) * * **************************************************************/void EmbraAnnExec(int cpuNum,AnnPtr ptr, int annType){   VA pc = EMP[cpuNum].PC;   ASSERT (!embraDebug.processingAnn);   ASSERT (annType);   if (embraDebug.ignoreNextOne) {       embraDebug.ignoreNextOne = 0;      if (DEBUG) {          CPUWarning("EmbraAnnExec: skipping annotation \n");      }      return;   }   embraDebug.statusCode &= ~(SIDE_EFFECT|FLUSH_TC);   embraDebug.processingAnn = annType;   AnnExec(ptr);   embraDebug.processingAnn = 0;   if (embraDebug.statusCode & FLUSH_TC) {       ASSERT (embraDebug.statusCode & SIDE_EFFECT);      Clear_Translation_State( TCFLUSH_ALL);   }   if (embraDebug.statusCode & SIDE_EFFECT) {      if (annType==ANNFM_LD_TYPE ||          annType==ANNFM_ST_TYPE ||          annType==ANNFM_PRE_PC_TYPE) {          if (EMP[cpuNum].PC == pc) {             embraDebug.ignoreNextOne = 1;         }      } else {          ASSERT (annType==ANNFM_PC_TYPE);         if (EMP[cpuNum].PC ==pc) {             /*             * there we better skip the instruction             * as some are not idempotent.             */            ASSERT( !IN_BD(EMP[cpuNum].PC));            EMP[cpuNum].PC += INST_SIZE;            EMP[cpuNum].cycleCountdown--;         }      }      ASSERT( !IN_BD(EMP[cpuNum].PC));      ReenterTC(&EMP[cpuNum]);      /* NOTREACHED */   }   embraDebug.statusCode &= ~FLUSH_TC;   embraDebug.statusCode &= ~SIDE_EFFECT;}   /* ************************************************************** * Callbacks during the gdb session. These have side-effects on

⌨️ 快捷键说明

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