Hello.

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".

    It seems that something has been broken WRT backtracing...

> Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>

> 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");

    Hm... should this panic() indeed be there?

>         return 0;
> +    }

WBR, Sergei

-------------------------------------------------------------------------
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