Thread overview
[Issue 14966] Comparing two std.xml.Document result in infinite recursion
Sep 01, 2015
Vladimir Panteleev
Sep 01, 2015
Jacob Carlborg
Sep 01, 2015
Vladimir Panteleev
Apr 03, 2016
Rainer Schuetze
Apr 04, 2016
Sobirari Muhomori
Apr 04, 2016
Rainer Schuetze
September 01, 2015
https://issues.dlang.org/show_bug.cgi?id=14966

Vladimir Panteleev <thecybershadow@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |thecybershadow@gmail.com

--- Comment #1 from Vladimir Panteleev <thecybershadow@gmail.com> ---
Please post a simple test case, sample stack trace... this is not a good bug report.

--
September 01, 2015
https://issues.dlang.org/show_bug.cgi?id=14966

--- Comment #2 from Jacob Carlborg <doob@me.com> ---
It's so obvious, that's why I didn't provide a test case. The content of the XML doesn't matter. I added a test case with a stack trace at the bottom.

I think the issue is that implementation of Document.opEquals:

override bool opEquals(Object o)
{
    const doc = toType!(const Document)(o);
    return
        (prolog != doc.prolog            ) ? false : (
        (super  != cast(const Element)doc) ? false : (
        (epilog != doc.epilog            ) ? false : (
    true )));
}

I suspect the issue is the super call. I'm guessing since the implementation of ==/!= was changed to call object.opEquals, which then calls opEquals on the object. The object will be dynamically resolved to Document and then call Document.opEquals again, resulting in infinite recursion. I was planning to ask about this in the newsgroup if this is a regression but forgot about it.

Test case:

$ cat main.d
import std.xml;

void main()
{
    auto xml = `
        <?xml version="1.0" encoding="UTF-8"?>
        <foo></foo>
    `;

    auto a = new Document(xml);
    auto b = new Document(xml);
    auto c = a == b;
}
$ dmd main.d && lldb main
(lldb) target create "main"
Current executable set to 'main' (x86_64).
(lldb) r
Process 68379 launched: '/Users/jacob/development/d/main' (x86_64)
Process 68379 stopped
* thread #1: tid = 0x4ad39f, 0x00000001000156f4 main`_d_isbaseof2 + 8, queue =
'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2,
address=0x7fff5f3fffa8)
    frame #0: 0x00000001000156f4 main`_d_isbaseof2 + 8
main`_d_isbaseof2:
->  0x1000156f4 <+8>:  pushq  %rbx
    0x1000156f5 <+9>:  pushq  %r12
    0x1000156f7 <+11>: pushq  %r13
    0x1000156f9 <+13>: pushq  %r14
(lldb) bt
* thread #1: tid = 0x4ad39f, 0x00000001000156f4 main`_d_isbaseof2 + 8, queue =
'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2,
address=0x7fff5f3fffa8)
  * frame #0: 0x00000001000156f4 main`_d_isbaseof2 + 8
    frame #1: 0x00000001000156d1 main`_d_dynamic_cast + 45
    frame #2: 0x00000001000361b8
main`D3std3xml31__T6toTypeTxC3std3xml8DocumentZ6toTypeFC6ObjectZxC3std3xml8Document
+ 20
    frame #3: 0x00000001000322f9 main`D3std3xml8Document8opEqualsMxFC6ObjectZb
+ 21
    frame #4: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb +
109
    frame #5: 0x00000001000019e5 main`D6object8opEqualsFxC6ObjectxC6ObjectZb +
13
    frame #6: 0x0000000100032334 main`D3std3xml8Document8opEqualsMxFC6ObjectZb
+ 80
    frame #7: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb +
109
    frame #8: 0x00000001000019e5 main`D6object8opEqualsFxC6ObjectxC6ObjectZb +
13
    frame #9: 0x0000000100032334 main`D3std3xml8Document8opEqualsMxFC6ObjectZb
+ 80
    frame #10: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb +
109
    .
    .
    .
    frame #196537: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb
+ 109
    frame #196538: 0x0000000100001236 main`_Dmain + 102
    frame #196539: 0x0000000100016b1c
main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 40
    frame #196540: 0x0000000100016a61
main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 45
    frame #196541: 0x0000000100016ac1
main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 45
    frame #196542: 0x0000000100016a61
main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 45
    frame #196543: 0x00000001000169d4 main`_d_run_main + 504
    frame #196544: 0x0000000100001254 main`main + 20
    frame #196545: 0x00007fff9a0295c9 libdyld.dylib`start + 1
    frame #196546: 0x00007fff9a0295c9 libdyld.dylib`start + 1
(lldb)

--
September 01, 2015
https://issues.dlang.org/show_bug.cgi?id=14966

--- Comment #3 from Vladimir Panteleev <thecybershadow@gmail.com> ---
(In reply to Jacob Carlborg from comment #2)
> It's so obvious, that's why I didn't provide a test case.

Ideally, bug reports should contain enough information so that people unfamiliar with the code in question could reproduce the problem - this is so anyone can check whether the bug has been fixed in the meanwhile, check if it's a regression, reduce the test case to a minimum one etc.

--
April 03, 2016
https://issues.dlang.org/show_bug.cgi?id=14966

Rainer Schuetze <r.sagitario@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull
                 CC|                            |r.sagitario@gmx.de

--- Comment #4 from Rainer Schuetze <r.sagitario@gmx.de> ---
https://github.com/D-Programming-Language/phobos/pull/4144

--
April 04, 2016
https://issues.dlang.org/show_bug.cgi?id=14966

--- Comment #5 from Sobirari Muhomori <dfj1esp02@sneakemail.com> ---
(In reply to Jacob Carlborg from comment #2)
> I suspect the issue is the super call. I'm guessing since the implementation of ==/!= was changed to call object.opEquals, which then calls opEquals on the object.

Awww, when?

--
April 04, 2016
https://issues.dlang.org/show_bug.cgi?id=14966

--- Comment #6 from Rainer Schuetze <r.sagitario@gmx.de> ---
> Awww, when?

I don't think this has to do with how Object.opEqual is called. The offending lines were changed a number of times, but I'd say none of them worked correctly (or there must have been a compiler change regarding super.calls). I suspect the bug is also in the original commit from 2008.

--
April 05, 2016
https://issues.dlang.org/show_bug.cgi?id=14966

--- Comment #7 from github-bugzilla@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/phobos

https://github.com/D-Programming-Language/phobos/commit/7cdd7098be255ec051831f9b56741701c6a1a57e fix issue 14966: misuse of super

https://github.com/D-Programming-Language/phobos/commit/0b99239fe9722de98c5aeb65deb09a27263b2a5a Merge pull request #4144 from rainers/issue_14966

fix issue 14966: misuse of super

--
April 05, 2016
https://issues.dlang.org/show_bug.cgi?id=14966

github-bugzilla@puremagic.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--