Using libbacktrace in libgfortran: some questions
Ian Lance Taylor
iant@google.com
Thu Aug 13 15:25:00 GMT 2015
On Thu, Aug 13, 2015 at 7:11 AM, FX <fxcoudert@gmail.com> wrote:
>
>> I don't know why this is not working. Everything looks fine in the
>> a.out that you sent. Unfortunately, I think you sent the one built
>> without libbacktrace. Can you send me the one built with libbacktrace?
>
> Attached is the a.out with libgfortran (and thus libbacktrace) linked in statically. If this isn’t sufficient, I can send any file necessary (including the whole tree if need be).
Thanks. The problem seems to be that gfortran is generating DWARF
info that looks like this:
subprogram test
subprogram foo
subprogram bar
libbacktrace does not expect to see this structure, and it thinks that
foo and bar have been inlined within test, which is not the case.
Please try this patch to libbacktrace and see if it helps.
Ian
-------------- next part --------------
diff -r 131549887d7c src/cmd/5g/cgen.c
--- a/src/cmd/5g/cgen.c Mon Apr 15 11:50:14 2013 -0700
+++ b/src/cmd/5g/cgen.c Tue Apr 23 16:45:14 2013 -0700
@@ -679,6 +679,19 @@
case ODOT:
agen(nl, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(nl->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], N);
+ gmove(res, &n1);
+ regalloc(&n2, types[TUINT8], &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gmove(&n1, &n2);
+ regfree(&n1);
+ regfree(&n2);
+ }
if(n->xoffset != 0) {
nodconst(&n1, types[TINT32], n->xoffset);
regalloc(&n2, n1.type, N);
@@ -694,20 +707,20 @@
case ODOTPTR:
cgen(nl, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(nl->type->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], N);
+ gmove(res, &n1);
+ regalloc(&n2, types[TUINT8], &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gmove(&n1, &n2);
+ regfree(&n1);
+ regfree(&n2);
+ }
if(n->xoffset != 0) {
- // explicit check for nil if struct is large enough
- // that we might derive too big a pointer.
- if(nl->type->type->width >= unmappedzero) {
- regalloc(&n1, types[tptr], N);
- gmove(res, &n1);
- regalloc(&n2, types[TUINT8], &n1);
- n1.op = OINDREG;
- n1.type = types[TUINT8];
- n1.xoffset = 0;
- gmove(&n1, &n2);
- regfree(&n1);
- regfree(&n2);
- }
nodconst(&n1, types[TINT32], n->xoffset);
regalloc(&n2, n1.type, N);
regalloc(&n3, types[tptr], N);
@@ -759,6 +772,19 @@
case ODOT:
igen(n->left, a, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(0 && n->left->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], N);
+ gmove(a, &n1);
+ regalloc(&n2, types[TUINT8], &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gmove(&n1, &n2);
+ regfree(&n1);
+ regfree(&n2);
+ }
a->xoffset += n->xoffset;
a->type = n->type;
return;
@@ -777,20 +803,18 @@
regalloc(a, types[tptr], res);
cgen(n->left, a);
}
- if(n->xoffset != 0) {
- // explicit check for nil if struct is large enough
- // that we might derive too big a pointer.
- if(n->left->type->type->width >= unmappedzero) {
- regalloc(&n1, types[tptr], N);
- gmove(a, &n1);
- regalloc(&n2, types[TUINT8], &n1);
- n1.op = OINDREG;
- n1.type = types[TUINT8];
- n1.xoffset = 0;
- gmove(&n1, &n2);
- regfree(&n1);
- regfree(&n2);
- }
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(n->left->type->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], N);
+ gmove(a, &n1);
+ regalloc(&n2, types[TUINT8], &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gmove(&n1, &n2);
+ regfree(&n1);
+ regfree(&n2);
}
a->op = OINDREG;
a->xoffset = n->xoffset;
diff -r 131549887d7c src/cmd/6g/cgen.c
--- a/src/cmd/6g/cgen.c Mon Apr 15 11:50:14 2013 -0700
+++ b/src/cmd/6g/cgen.c Tue Apr 23 16:45:14 2013 -0700
@@ -882,24 +882,35 @@
case ODOT:
agen(nl, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(nl->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], res);
+ gmove(res, &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
+ regfree(&n1);
+ }
if(n->xoffset != 0)
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
break;
case ODOTPTR:
cgen(nl, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(nl->type->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], res);
+ gmove(res, &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
+ regfree(&n1);
+ }
if(n->xoffset != 0) {
- // explicit check for nil if struct is large enough
- // that we might derive too big a pointer.
- if(nl->type->type->width >= unmappedzero) {
- regalloc(&n1, types[tptr], res);
- gmove(res, &n1);
- n1.op = OINDREG;
- n1.type = types[TUINT8];
- n1.xoffset = 0;
- gins(ATESTB, nodintconst(0), &n1);
- regfree(&n1);
- }
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
}
break;
@@ -944,22 +955,29 @@
case ODOT:
igen(n->left, a, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(0 && n->left->type->width >= unmappedzero) {
+ n1 = *a;
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
+ }
a->xoffset += n->xoffset;
a->type = n->type;
return;
case ODOTPTR:
cgenr(n->left, a, res);
- if(n->xoffset != 0) {
- // explicit check for nil if struct is large enough
- // that we might derive too big a pointer.
- if(n->left->type->type->width >= unmappedzero) {
- n1 = *a;
- n1.op = OINDREG;
- n1.type = types[TUINT8];
- n1.xoffset = 0;
- gins(ATESTB, nodintconst(0), &n1);
- }
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(n->left->type->type->width >= unmappedzero) {
+ n1 = *a;
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
}
a->op = OINDREG;
a->xoffset += n->xoffset;
@@ -1009,6 +1027,9 @@
}
// Compute &a[i] as &a + i*width.
+ if(0 && 0) {
+ // TODO: needed? also in 5g/8g.
+ }
a->type = n->type;
a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
return;
diff -r 131549887d7c src/cmd/8g/cgen.c
--- a/src/cmd/8g/cgen.c Mon Apr 15 11:50:14 2013 -0700
+++ b/src/cmd/8g/cgen.c Tue Apr 23 16:45:14 2013 -0700
@@ -739,6 +739,17 @@
case ODOT:
agen(nl, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(nl->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], res);
+ gmove(res, &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
+ regfree(&n1);
+ }
if(n->xoffset != 0) {
nodconst(&n1, types[tptr], n->xoffset);
gins(optoas(OADD, types[tptr]), &n1, res);
@@ -750,18 +761,18 @@
if(!isptr[t->etype])
fatal("agen: not ptr %N", n);
cgen(nl, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(nl->type->type->width >= unmappedzero) {
+ regalloc(&n1, types[tptr], res);
+ gmove(res, &n1);
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
+ regfree(&n1);
+ }
if(n->xoffset != 0) {
- // explicit check for nil if struct is large enough
- // that we might derive too big a pointer.
- if(nl->type->type->width >= unmappedzero) {
- regalloc(&n1, types[tptr], res);
- gmove(res, &n1);
- n1.op = OINDREG;
- n1.type = types[TUINT8];
- n1.xoffset = 0;
- gins(ATESTB, nodintconst(0), &n1);
- regfree(&n1);
- }
nodconst(&n1, types[tptr], n->xoffset);
gins(optoas(OADD, types[tptr]), &n1, res);
}
@@ -804,6 +815,15 @@
case ODOT:
igen(n->left, a, res);
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(0 && n->left->type->width >= unmappedzero) {
+ n1 = *a;
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
+ }
a->xoffset += n->xoffset;
a->type = n->type;
return;
@@ -825,16 +845,14 @@
regalloc(a, types[tptr], res);
cgen(n->left, a);
}
- if(n->xoffset != 0) {
- // explicit check for nil if struct is large enough
- // that we might derive too big a pointer.
- if(n->left->type->type->width >= unmappedzero) {
- n1 = *a;
- n1.op = OINDREG;
- n1.type = types[TUINT8];
- n1.xoffset = 0;
- gins(ATESTB, nodintconst(0), &n1);
- }
+ // explicit check for nil if struct is large enough
+ // that we might derive too big a pointer.
+ if(n->left->type->type->width >= unmappedzero) {
+ n1 = *a;
+ n1.op = OINDREG;
+ n1.type = types[TUINT8];
+ n1.xoffset = 0;
+ gins(ATESTB, nodintconst(0), &n1);
}
a->op = OINDREG;
a->xoffset += n->xoffset;
diff -r 131549887d7c test/nilptr.go
--- a/test/nilptr.go Mon Apr 15 11:50:14 2013 -0700
+++ b/test/nilptr.go Tue Apr 23 16:45:14 2013 -0700
@@ -38,6 +38,8 @@
shouldPanic(p8)
shouldPanic(p9)
shouldPanic(p10)
+ shouldPanic(p11)
+ shouldPanic(p12)
}
func shouldPanic(f func()) {
@@ -130,3 +132,23 @@
var t *T
println(t.i) // should crash
}
+
+type T1 struct {
+ T
+}
+
+type T2 struct {
+ *T1
+}
+
+func p11() {
+ t := &T2{}
+ p := &t.i
+ println(*p)
+}
+
+// ADDR(DOT(IND(p))) needs a check also
+func p12() {
+ var p *T = nil
+ println(*(&((*p).i)))
+}
More information about the Fortran
mailing list