Hi Matthias, > #0 build_goto_dest (document=<optimized out>, action=<optimized out>, link=0x0) at \ > /home/ports/pobj/p2/poppler-0.86.1/poppler-0.86.1/glib/poppler-action.cc:348 348 \ > if (! link->isOk ()) { [Current thread is 1 (process 435846)] > (gdb) print link > $1 = (const LinkGoTo *) 0x0 > (gdb) up > #1 _poppler_action_new (document=0x280b77b5c00, link=0x2812b023d40, title=<optimized \ > out>) at /home/ports/pobj/p2/poppler-0.86.1/poppler-0.86.1/glib/poppler-action.cc:630 \ > 630 build_goto_dest (document, action, dynamic_cast <const \ > LinkGoTo *> (link)); (gdb) print link > $2 = (const LinkAction *) 0x2812b023d40 > (gdb)
> I'm not a C++ magician, especially if it comes to things like that > dynamic_cast, but it really looks odd to me that this pointer is > NULL in the callee while it's not NULL in the caller. I hope I'm not belaboring the obvious here. This condition seems a fairly direct result of an unchecked dynamic_cast. Per C++ dynamic_cast description: "If the cast fails and new-type is a pointer type, it returns a null pointer of that type." https://en.cppreference.com/w/cpp/language/dynamic_cast This just means that the downcast was a mistake, LinkAction* is NOT a LinkGoTo*, but some other subclass of LinkAction of which there is a bunch: Link.h:161:class LinkGoTo: public LinkAction { Link.h:187:class LinkGoToR: public LinkAction { Link.h:216:class LinkLaunch: public LinkAction { Link.h:240:class LinkURI: public LinkAction { Link.h:263:class LinkNamed: public LinkAction { Link.h:285:class LinkMovie: public LinkAction { Link.h:324:class LinkRendition: public LinkAction { Link.h:372:class LinkSound: public LinkAction { Link.h:400:class LinkJavaScript: public LinkAction { Link.h:422:class LinkOCGState: public LinkAction { Link.h:453:class LinkHide: public LinkAction { Link.h:486:class LinkUnknown: public LinkAction { I don't see how this can be the case if type safety were respected. The only place where actionGoTo is returned from getKind is in LinkGoTo class. Though I can't say I'm surprised, the number of static_cast and C-style casts around these types is so high I won't expect any type safety in the program. If one wanted to paper over the problem they could rewrite _poppler_action_new "defensively" and make the program fallback locally to POPPLER_ACTION_NONE. This would avoid the crash, but I suspect the memory is borked by that point and something else will crash instead. Out of curiosity, is MALLOC_OPTIONS any help? If repro is easy, maybe rebuild on an OS with ASan support and see what you get from that? Thanks Greg -- nest.cx is Gmail hosted, use PGP: https://pgp.key-server.io/0x0B1542BD8DF5A1B0 Fingerprint: 5E2B 2D0E 1E03 2046 BEC3 4D50 0B15 42BD 8DF5 A1B0