Jason,

That's a good patch. Instead of relying on kernel's mechanism to panic, this 
way we do something more reliable to report the panic to a user.

-Amit


On Tuesday 15 May 2007 08:39, Jason Wessel wrote:
> If there are no objections, I will commit the following patch.
>
> --
>
> This patch fixes some corner cases where KGDB will silently hang or
> kill the system, if a user accidentally tries to source step into a
> spin_unlock() call or source step in on a macro containing
> smp_processor_id().  The use of raw_smp_processor_id is desired in
> kernel/kgdb.c to fix this particular problem.
>
> To fix issues with accidental source step in on spin_unlock(), the
> idea is to check for the existence of a break point on the second
> entry to kgdb and try to remove it.  Next an attempt will be made to
> continue normal operations.  A third entry will generate a panic(), so
> as to stop infinite loops.
>
> Testing has shown that kgdb is much more robust with these changes
> and "random accidental run control".
>
> Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>
>
> ---
>  arch/i386/kernel/kgdb.c |    8 ++++++++
>  kernel/kgdb.c           |   47
> ++++++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 48 insertions(+), 7 deletions(-)
>
> Index: linux-2.6.21.1/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21.1.orig/kernel/kgdb.c
> +++ linux-2.6.21.1/kernel/kgdb.c
> @@ -70,6 +70,8 @@ int kgdb_connected;
>  int kgdb_may_fault;
>  /* All the KGDB handlers are installed */
>  int kgdb_from_module_registered = 0;
> +/* Guard for recursive entry */
> +static int exception_level = 0;
>
>  /* We provide a kgdb_io_ops structure that may be overriden. */
>  struct kgdb_io __attribute__ ((weak)) kgdb_io_ops;
> @@ -166,6 +168,12 @@ int __attribute__ ((weak))
>      return 0;
>  }
>
> +unsigned long __attribute__ ((weak))
> +    kgdb_arch_pc(int exception, struct pt_regs *regs)
> +{
> +    return instruction_pointer(regs);
> +}
> +
>  static int hex(char ch)
>  {
>      if ((ch >= 'a') && (ch <= 'f'))
> @@ -580,11 +588,11 @@ static void kgdb_wait(struct pt_regs *re
>      int processor;
>
>      local_irq_save(flags);
> -    processor = smp_processor_id();
> +    processor = raw_smp_processor_id();
>      kgdb_info[processor].debuggerinfo = regs;
>      kgdb_info[processor].task = current;
>      atomic_set(&procindebug[processor], 1);
> -    atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1);
> +    atomic_set(&kgdb_sync_softlockup[raw_smp_processor_id()], 1);
>
>      /* Wait till master processor goes completely into the debugger.
>       * FIXME: this looks racy */
> @@ -784,7 +792,7 @@ static inline int shadow_pid(int realpid
>      if (realpid) {
>          return realpid;
>      }
> -    return pid_max + smp_processor_id();
> +    return pid_max + raw_smp_processor_id();
>  }
>
>  static char gdbmsgbuf[BUFMAX + 1];
> @@ -848,12 +856,36 @@ int kgdb_handle_exception(int ex_vector,
>      long kgdb_usethreadid = 0;
>      int error = 0, all_cpus_synced = 0;
>      struct pt_regs *shadowregs;
> -    int processor = smp_processor_id();
> +    int processor = raw_smp_processor_id();
>      void *local_debuggerinfo;
>
>      /* Panic on recursive debugger calls. */
> -    if (atomic_read(&debugger_active) == smp_processor_id() + 1)
> +    if (atomic_read(&debugger_active) == raw_smp_processor_id() + 1) {
> +        exception_level++;
> +        addr = kgdb_arch_pc(ex_vector, linux_regs);
> +        kgdb_deactivate_sw_breakpoints();
> +        if (kgdb_remove_sw_break(addr) == 0) {
> +            /* If the break point removed ok at the place exception
> +             * occurred, try to recover and print a warning to the end
> +             * user because the user planted a breakpoint in a place
> +             * that KGDB needs in order to function.
> +             */
> +            exception_level = 0;
> +            kgdb_skipexception(ex_vector, linux_regs);
> +            kgdb_activate_sw_breakpoints();
> +            printk(KERN_CRIT "KGDB: re-enter exception: breakpoint
> removed\n");
> +            WARN_ON(1);
> +            return 0;
> +        }
> +        remove_all_break();
> +        kgdb_skipexception(ex_vector, linux_regs);
> +        if (exception_level > 1)
> +            panic("Recursive entry to debugger");
> +
> +        printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints
> removed\n");
> +        panic("Recursive entry to debugger");
>          return 0;
> +    }
>
>   acquirelock:
>
> @@ -864,7 +896,7 @@ int kgdb_handle_exception(int ex_vector,
>      local_irq_save(flags);
>
>      /* Hold debugger_active */
> -    procid = smp_processor_id();
> +    procid = raw_smp_processor_id();
>
>      while (cmpxchg(&atomic_read(&debugger_active), 0, (procid + 1)) != 0)
> { int i = 25;    /* an arbitrary number */
> @@ -877,7 +909,7 @@ int kgdb_handle_exception(int ex_vector,
>              udelay(1);
>      }
>
> -    atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1);
> +    atomic_set(&kgdb_sync_softlockup[raw_smp_processor_id()], 1);
>
>      /*
>       * Don't enter if the last instance of the exception handler wanted to
> @@ -945,6 +977,7 @@ int kgdb_handle_exception(int ex_vector,
>      kgdb_deactivate_sw_breakpoints();
>      debugger_step = 0;
>      kgdb_contthread = NULL;
> +    exception_level = 0;
>
>      if (kgdb_connected) {
>          /* If we're still unable to roundup all of the CPUs,
> Index: linux-2.6.21.1/arch/i386/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21.1.orig/arch/i386/kernel/kgdb.c
> +++ linux-2.6.21.1/arch/i386/kernel/kgdb.c
> @@ -302,6 +302,14 @@ int kgdb_skipexception(int exception, st
>      return 0;
>  }
>
> +unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs)
> +{
> +    if (exception == 3) {
> +        return instruction_pointer(regs) - 1;
> +    }
> +    return instruction_pointer(regs);
> +}
> +
>  struct kgdb_arch arch_kgdb_ops = {
>      .gdb_bpt_instr = {0xcc},
>      .flags = KGDB_HW_BREAKPOINT,
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Kgdb-bugreport mailing list
> Kgdb-bugreport@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Kgdb-bugreport mailing list
Kgdb-bugreport@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to