Three classes Rule, ElementRule and QueryRule define
int compareSpecificity(const Rule &) const;
int compareSpecificity2(const ElementRule *) const;
int compareSpecificity2(const QueryRule *) const;
Per Backtrace we seem to be in a "Rule" object but since the passed
object is optimized out I don't see the rule type. But all three
implementations are defined as:
int ProcessingMode::Rule::compareSpecificity2(const RootRule *rule) const
{
return - compareParts(rule);
}
And that is:
int ProcessingMode::Rule::compareParts(const Rule *r) const
{
unsigned i1 = action().partIndex();
unsigned i2 = r->action().partIndex();
if (i1 == i2)
return 0;
return i1 < i2 ? -1 : 1;
}
I don't see the path to erase() anywhere in here. The optimization has torn
this so much apart that I can't completely unwind the stack as needed.
With some gdb magic I was able to verify that on the way to death I pass:
Breakpoint 4, OpenJade_DSSSL::ProcessingMode::RootRule::compareSpecificity2
(this=0xaaaaaaeb58b0, rule=0xaaaaaae96ba0) at ProcessingMode.cxx:344
That is:
int ProcessingMode::RootRule::compareSpecificity2(const RootRule *rule) const
{
int result = Rule::compareSpecificity2(rule);
if (result)
return result;
return 0;
}
And the two objects are not yet optimized out:
(gdb) p *this
$5 = {<OpenJade_DSSSL::ProcessingMode::Rule> = {<OpenJade_DSSSL::MatchBase> =
{_vptr.MatchBase = 0xfffff7fa97b0 <vtable for
OpenJade_DSSSL::ProcessingMode::RootRule+88>, trivial_ = true},
_vptr.Rule = 0xfffff7fa9770 <vtable for
OpenJade_DSSSL::ProcessingMode::RootRule+24>, action_ = {ptr_ =
0xaaaaaaeb5b80}}, <No data fields>}
(gdb) p *rule
$6 = {<OpenJade_DSSSL::ProcessingMode::Rule> = {<OpenJade_DSSSL::MatchBase> =
{_vptr.MatchBase = 0xfffff7fa97b0 <vtable for
OpenJade_DSSSL::ProcessingMode::RootRule+88>, trivial_ = true},
_vptr.Rule = 0xfffff7fa9770 <vtable for
OpenJade_DSSSL::ProcessingMode::RootRule+24>, action_ = {ptr_ =
0xaaaaaae96b50}}, <No data fields>}
That seems to be the same rule but with different actions:
(gdb) p *(this->action_.ptr_)
$10 = {<OpenSP::Resource> = {count_ = 2}, defLoc_ = <incomplete type>, expr_ =
{_vptr.Owner = 0xfffff7f98fb8 <vtable for
OpenSP::Owner<OpenJade_DSSSL::Expression>+16>,
p_ = 0xaaaaaaeb5b10}, insn_ = {<OpenSP::Ptr<OpenJade_DSSSL::Insn>> = {ptr_
= 0x0}, <No data fields>}, sosofo_ = 0x0, partIndex_ = 2}
(gdb) p *(rule->action_.ptr_)
$9 = {<OpenSP::Resource> = {count_ = 1}, defLoc_ = <incomplete type>, expr_ =
{_vptr.Owner = 0xfffff7f98fb8 <vtable for
OpenSP::Owner<OpenJade_DSSSL::Expression>+16>, p_ = 0xaaaaaae96b00},
insn_ = {<OpenSP::Ptr<OpenJade_DSSSL::Insn>> = {ptr_ = 0x0}, <No data
fields>}, sosofo_ = 0x0, partIndex_ = 1}
That is at:
#0 OpenJade_DSSSL::ProcessingMode::RootRule::compareSpecificity2
(this=0xaaaaaaeb58b0, rule=0xaaaaaae96ba0) at ProcessingMode.cxx:344
#1 0x0000fffff7ee3038 in
OpenJade_DSSSL::ProcessingMode::RootRule::compareSpecificity (this=<optimized
out>, rule=...) at ProcessingMode.cxx:331
#2 0x0000fffff7ee4dc0 in OpenJade_DSSSL::ProcessingMode::addRootRule
(this=<optimized out>, expr=...,
ruleType=OpenJade_DSSSL::ProcessingMode::constructionRule, loc=..., interp=...)
at /usr/include/OpenSP/Vector.h:49
#3 0x0000fffff7eec698 in OpenJade_DSSSL::SchemeParser::doRoot
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:484
#4 0x0000fffff7ef4254 in OpenJade_DSSSL::SchemeParser::parse
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:190
It then goes up as it calls the parent Objects method:
0x0000fffff7e703a0 in
OpenJade_DSSSL::ProcessingMode::Rule::compareSpecificity2(OpenJade_DSSSL::ProcessingMode::RootRule
const*) const@plt () from /lib/libostyle.so.1
That is just:
int ProcessingMode::Rule::compareSpecificity2(const RootRule *rule) const
{
return - compareParts(rule);
}
And compareParts is just:
int ProcessingMode::Rule::compareParts(const Rule *r) const
{
unsigned i1 = action().partIndex();
unsigned i2 = r->action().partIndex();
if (i1 == i2)
return 0;
return i1 < i2 ? -1 : 1;
}
We get a bunch of jumps via the PLT now.
(gdb) bt
#0 0x0000fffff7e703a4 in
OpenJade_DSSSL::ProcessingMode::Rule::compareSpecificity2(OpenJade_DSSSL::ProcessingMode::RootRule
const*) const@plt () from /lib/libostyle.so.1
#1 0x0000fffff7ee3038 in
OpenJade_DSSSL::ProcessingMode::RootRule::compareSpecificity (this=<optimized
out>, rule=...) at ProcessingMode.cxx:331
#2 0x0000fffff7ee4dc0 in OpenJade_DSSSL::ProcessingMode::addRootRule
(this=<optimized out>, expr=...,
ruleType=OpenJade_DSSSL::ProcessingMode::constructionRule, loc=..., interp=...)
at /usr/include/OpenSP/Vector.h:49
#3 0x0000fffff7eec698 in OpenJade_DSSSL::SchemeParser::doRoot
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:484
#4 0x0000fffff7ef4254 in OpenJade_DSSSL::SchemeParser::parse
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:190
It then reaches compareParts as expected
#0 0x0000fffff7e724b4 in
OpenJade_DSSSL::ProcessingMode::Rule::compareParts(OpenJade_DSSSL::ProcessingMode::Rule
const*) const@plt () from /lib/libostyle.so.1
#1 0x0000fffff7ee345c in
OpenJade_DSSSL::ProcessingMode::Rule::compareSpecificity2 (this=<optimized
out>, rule=<optimized out>) at ProcessingMode.cxx:144
#2 0x0000fffff7ee3038 in
OpenJade_DSSSL::ProcessingMode::RootRule::compareSpecificity (this=<optimized
out>, rule=...) at ProcessingMode.cxx:331
#3 0x0000fffff7ee4dc0 in OpenJade_DSSSL::ProcessingMode::addRootRule
(this=<optimized out>, expr=...,
ruleType=OpenJade_DSSSL::ProcessingMode::constructionRule, loc=..., interp=...)
at /usr/include/OpenSP/Vector.h:49
#4 0x0000fffff7eec698 in OpenJade_DSSSL::SchemeParser::doRoot
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:484
#5 0x0000fffff7ef4254 in OpenJade_DSSSL::SchemeParser::parse
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:190
It seems that on calling
unsigned i1 = action().partIndex();
unsigned i2 = r->action().partIndex();
it looses tracking:
#0 0x0000fffff7e6dcd0 in ?? () from /lib/libostyle.so.1
#1 0x0000fffff7ee345c in
OpenJade_DSSSL::ProcessingMode::Rule::compareSpecificity2 (this=<optimized
out>, rule=<optimized out>) at ProcessingMode.cxx:144
#2 0x0000fffff7ee3038 in
OpenJade_DSSSL::ProcessingMode::RootRule::compareSpecificity (this=<optimized
out>, rule=...) at ProcessingMode.cxx:331
#3 0x0000fffff7ee4dc0 in OpenJade_DSSSL::ProcessingMode::addRootRule
(this=<optimized out>, expr=...,
ruleType=OpenJade_DSSSL::ProcessingMode::constructionRule, loc=..., interp=...)
at /usr/include/OpenSP/Vector.h:49
#4 0x0000fffff7eec698 in OpenJade_DSSSL::SchemeParser::doRoot
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:484
#5 0x0000fffff7ef4254 in OpenJade_DSSSL::SchemeParser::parse
(this=this@entry=0xffffffffe7b0) at SchemeParser.cxx:190
In there one can't single step, but it doesn't crash yet.
It returns and identifies an action.
240 inline
241 const ProcessingMode::Action &ProcessingMode::Rule::action() const
242 {
243 return *action_;
244 }
(gdb) n
161 if (i1 == i2)
(gdb) p i1
$14 = 2
(gdb) p i2
$15 = 1
With that ProcessingMode::Rule::compareParts will return "1".
But this is where the optimization kicks in , the next single step is
Breakpoint 1, OpenSP::Vector<OpenJade_DSSSL::ProcessingMode::Rule*>::erase
(p1=0x1, p2=0x2, this=<optimized out>, this=<optimized out>) at
/usr/include/OpenSP/Vector.cxx:131
While there is no obious call to ::erase not even a destructor call or such
that would explain.
But due to that we miss how these bad pointers 0x1/0x2 got passed here.
That will
--
You received this bug notification because you are a member of Desktop
Packages, which is subscribed to openjade in Ubuntu.
https://bugs.launchpad.net/bugs/1869734
Title:
openjade segfaults on arm (due to gcc optimization)
Status in openjade package in Ubuntu:
Triaged
Bug description:
<Myon> cpaelzer: fun, openjade segfaulting on focal/arm64
<cpaelzer> I beg your pardon for my ignorance of the ecosystem, but how is
this related to postgresql-apt
<cpaelzer> for doc generation?
<Myon> cpaelzer: the postgresql-9.5 and -9.6 builds fail during doc
generation on focal/arm64
<Myon> everything else (other archs, other dists) is fine
<Myon>
https://pgdgbuild.dus.dg-i.net/job/postgresql-9.5-binaries/architecture=arm64,distribution=focal/55/console
<cpaelzer> Myon: only on arm64?
<Myon> only there, yes
<Myon> ./configure && make -C doc/src/sgml all should reproduce it
<cpaelzer> clone and build this branch ?
https://github.com/postgres/postgres/tree/REL9_5_STABLE
<Myon> the crash is in /usr/lib/libostyle.so.1 from libostyle1c2
<cpaelzer> here it is
<cpaelzer> segfault
<Myon> I have this now http://paste.debian.net/1136839/
<cpaelzer> https://paste.ubuntu.com/p/CfzrfWkqzs/
<cpaelzer> well I wanted to get -O0 to see more int he debugger
<cpaelzer> my build worked as well now
<Myon> the -O0 openjade installed doesn't segfault
<cpaelzer> oh so like my -O0 then
<cpaelzer> so maybe we should just always -O0 openjade then?
<cpaelzer> TBH who cares about optimization in that
<cpaelzer> But its usage is mostly build time and not runtime
<Myon> maybe -O0 on arm64 only
<cpaelzer> I'm rebulding -O2 again to recheck if that really is it
<cpaelzer> and then -O1 to check the in between
<cpaelzer> it might "just" need a rebuild
<cpaelzer> -O2 re-build segfault
<cpaelzer> -O1 (for completeness) rebuild ... seems to hang?
<Myon> probably not really relevant
<cpaelzer> agreed, but I want to rebuild -O0 again just to see it builds
and then works
<cpaelzer> -O0 on arm64 really seems to be a good choice
<Myon> I can try if rebuilding makes it fail on sid
<Myon> cpaelzer: recompiling openjade in arm64/sid doesn't make it
segfault
<Myon> so it seems this needs a focal-only fix
<Myon> cpaelzer: the openjade segfault is also present in pgpool2, so
not just in ancient PostgreSQL :(
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/openjade/+bug/1869734/+subscriptions
--
Mailing list: https://launchpad.net/~desktop-packages
Post to : [email protected]
Unsubscribe : https://launchpad.net/~desktop-packages
More help : https://help.launchpad.net/ListHelp