From nobody Thu Apr 14 16:36:24 2022 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id A3B9D1B32910 for ; Thu, 14 Apr 2022 16:36:40 +0000 (UTC) (envelope-from jbo@insane.engineer) Received: from mail-4018.proton.ch (mail-4018.proton.ch [185.70.40.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "protonmail.com", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KfQ8Q3Lp7z3jgB for ; Thu, 14 Apr 2022 16:36:38 +0000 (UTC) (envelope-from jbo@insane.engineer) Date: Thu, 14 Apr 2022 16:36:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=insane.engineer; s=protonmail2; t=1649954190; bh=wYdDXoOOMtZtAJLU7hA1xF2P2ZdB4vANX/SbtfmWA0o=; h=Date:To:From:Reply-To:Subject:Message-ID:From:To:Cc:Date:Subject: Reply-To:Feedback-ID:Message-ID; b=q1VpSu1dzyd8/B7bdFS8DCwwQIRXLiFE1Mey6dWGIwBYy1Qhuh7LZg7+HJs5qkOs1 7OCD2nXDy6u3nzbbc43hgH45x8mYUbZARjgg1zsZ6668qf/Yf0zX1RXEk3QN9ptqbJ mWO1NLg1GfPYi0u8iIdvK2KaMZ52U54JKN1a7jRvVePtmk+xDXIkpqOdoZ9R2UP3vH iwzbkHB1ekZAF/yvDiXBn2f3zOmGJ7EUItv4YnzOg+jj2HvNUmyMphSxCpslLWVTe4 otsPHljEJFqhXbBaS6YJLyQeAjSQ8r2cj+KcHyhMzVRO9zIbCrXFDPLgKgskTp59Fw eoTbBg1PtfCFw== To: "freebsd-hackers@freebsd.org" From: jbo@insane.engineer Reply-To: jbo@insane.engineer Subject: llvm & RTTI over shared libraries Message-ID: List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 4KfQ8Q3Lp7z3jgB X-Spamd-Bar: --- Authentication-Results: mx1.freebsd.org; dkim=pass header.d=insane.engineer header.s=protonmail2 header.b=q1VpSu1d; dmarc=pass (policy=none) header.from=insane.engineer; spf=pass (mx1.freebsd.org: domain of jbo@insane.engineer designates 185.70.40.18 as permitted sender) smtp.mailfrom=jbo@insane.engineer X-Spamd-Result: default: False [-3.17 / 15.00]; HAS_REPLYTO(0.00)[jbo@insane.engineer]; ARC_NA(0.00)[]; R_DKIM_ALLOW(-0.20)[insane.engineer:s=protonmail2]; REPLYTO_EQ_FROM(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:185.70.40.0/24]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; RCPT_COUNT_ONE(0.00)[1]; DKIM_TRACE(0.00)[insane.engineer:+]; DMARC_POLICY_ALLOW(-0.50)[insane.engineer,none]; FROM_NO_DN(0.00)[]; NEURAL_HAM_SHORT(-0.47)[-0.466]; MIME_HTML_ONLY(0.20)[]; MLMMJ_DEST(0.00)[freebsd-hackers]; RCVD_COUNT_ZERO(0.00)[0]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:~]; TO_DN_EQ_ADDR_ALL(0.00)[]; ASN(0.00)[asn:62371, ipnet:185.70.40.0/24, country:CH]; MID_RHS_MATCH_FROM(0.00)[]; RWL_MAILSPIKE_VERYGOOD(0.00)[185.70.40.18:from] X-ThisMailContainsUnwantedMimeParts: N Hello folks! I'm in the middle of moving to FreeBSD as my primary development platform (= desktop wise). As such, I am currently building various software tools I've written over t= he years on FreeBSD for the first time. Most of those were developed on eit= her Linux+GCC or on Windows+Mingw (MinGW -> GCC). Today I found myself debugging a piece of software which runs fine on FreeB= SD when compiled with gcc11 but not so much when compiling with clang14. I managed to track down the problem but I lack the deeper understanding to = resolve this properly - so here we are. The software in question is written in C++20 and consisting of: - An interface library (just a bunch of header files). - A main executable. - A bunch of plugins which the executable loads via dlopen(). The interface headers provide several types. Lets call them A, B, C and D. = where B, C and D inherit from A. The plugins use std::dynamic_pointer_cast() to cast an std::shared_ptr (= received via the plugin interface) to the derived classes such as std::shar= ed_ptr. This is where the trouble begins. If everything (the main executable and the plugins) are compiled using gcc1= 1, everything works "as I expect it". However, when compiling everything with clang14, the main executable is abl= e to load the plugins successfully but those std::dynamic_pointer_cast() ca= lls within the plugins always return nullptr. After some research I seem to understand that the way that RTTI is handled = over shared library boundaries is different between GCC and LLVM. This is where my understanding starts to get less solid. I read the manual page of dlopen(3). It would seem like the flag RTLD_GLOBA= L would be potentially interesting to me: "Symbols from this shared object = [...] of needed objects will be available for re-solving undefined referenc= es from all other shared objects." The software (which "works as intended" when compiled with GCC) was so far = only calling dlopen(..., RTLD_LAZY). I'm not even sure whether this applies to my situation. My gut feeling tell= s me that I'm heading down the wrong direction here. After all, the main ex= ecutable is able to load the plugins and to call the plugin's function whic= h receives an std::shared_ptr as parameter just fine, also when compiled= with LLVM. Is the problem I'm experiencing related to the way that the plugin (shared = library) is loaded or the way that the symbols are being exported? In the current state, the plugins do not explicitly export any symbols. Here's a heavily simplified version of my scenario: =3D=3D=3D interface.hpp =3D=3D=3D struct A {}; struct B : A {}; struct C : A {}; struct D : A {}; struct plugin { virtual void do_stuff(std::shared_ptr in); }; =3D=3D=3D plugin1 =3D=3D=3D struct plugin1 : plugin { void do_stuff(std::shared_ptr a) override { auto b =3D std::dynamic_pointer_cast(a); if (!b) return; // GCC -> success // LLVM -> b always nullptr } }; Could you guys help me out here? Best regards, ~ Joel