Fix mips64 ddb backtracing

Juli Mallett jmallett at FreeBSD.org
Thu May 27 18:35:10 UTC 2010


On Thu, May 27, 2010 at 09:03, M. Warner Losh <imp at bsdimp.com> wrote:
> : @@ -140,7 +150,7 @@
> :       }
> :       /* check for bad SP: could foul up next frame */
> :       /*XXX MIPS64 bad: this hard-coded SP is lame */
> : -     if (sp & 3 || sp < 0x80000000) {
> : +     if (sp & 3 || (uintptr_t) sp < 0xffffffff80000000ULL) {
>
> This is wrong.  sp should be cast to intptr_t to have it still work
> with 32-bit debugging.  Unsigned sp will be 0x80000000, which will
> trigger this case.

Actually, it's worse than that.  As far as unsigned quantities go,
XKPHYS and XKSEG addresses are less than CKSEG0 addresses, so if your
thread is using an at all 64-bit aware kernel, you're going to have
trouble here.  The right thing to do is to check for whether the high
bit is set.  Checking whether (intptr_t)sp is negative is probably the
closest thing to a universal solution you're going to want.

> :               (*printfn) ("SP 0x%x: not in kernel\n", sp);
> :               ra =3D 0;
> :               subr =3D 0;
> : @@ -181,7 +191,7 @@
> :       }
> :       /* check for bad PC */
> :       /*XXX MIPS64 bad: These hard coded constants are lame */
> : -     if (pc & 3 || pc < (uintptr_t)0x80000000) {
> : +     if (pc & 3 || (uintptr_t)pc < 0xffffffff80000000ULL) {
>
> Ditto.

Likewise.

> :               (*printfn) ("PC 0x%x: not in kernel\n", pc);
> :               ra =3D 0;
> :               goto done;
> : @@ -337,17 +349,18 @@
> :       }
> : =20
> :  done:
> : -     (*printfn) ("%s+%x (", fn_name(subr), pc - subr);
> : +     (*printfn) ("%s+%lx (", fn_name(subr), (unsigned long) (pc - subr));
> :       for (j =3D 0; j < 4; j ++) {
> :               if (j > 0)
> :                       (*printfn)(",");
> :               if (valid_args[j])
> : -                     (*printfn)("%x", args[j]);
> : +                     (*printfn)("%lx", (unsigned long) args[j]);
>
> These casts aren't right.  We should likely be using intmax_t here and
> %j.

Yep.

> :               else
> :                       (*printfn)("?");
> :       }
> : =20
> : -     (*printfn) (") ra %x sp %x sz %d\n", ra, sp, stksize);
> : +     (*printfn) (") ra %lx sp %lx sz %ld\n", (unsigned long) ra,
> : +                 (unsigned long) sp, (long) stksize);
> : =20
>
> These casts aren't right.  We should likely be using intmax_t here and
> %j.

I agree once again :)

> :       if (ra) {
> :               if (pc =3D=3D ra && stksize =3D=3D 0)
> :

Juli.


More information about the freebsd-mips mailing list