From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7272 invoked by alias); 30 Oct 2018 16:31:55 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 7257 invoked by uid 89); 30 Oct 2018 16:31:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00,KAM_SHORT,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=irrespective X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 30 Oct 2018 16:31:53 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8CDCF3082E53; Tue, 30 Oct 2018 16:31:52 +0000 (UTC) Received: from [127.0.0.1] (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 860485D78F; Tue, 30 Oct 2018 16:31:51 +0000 (UTC) Subject: Re: [PATCH v3 3/3] Aarch64: Fix segfault when casting dummy calls To: Alan Hayward References: <20181011144905.66908-1-alan.hayward@arm.com> <20181011144905.66908-4-alan.hayward@arm.com> <95a5dd34-6815-f3f5-107c-13f4956b741e@redhat.com> <9290BC71-862C-48B1-97FD-A46C5D15A65C@arm.com> <201c7a49-ddf3-636a-f15a-eb9a4ccf284e@redhat.com> <3FFDA486-3FC8-4DA2-92C9-83C320F589F6@arm.com> <862cf8f4-9491-a1eb-251e-6c7c1ffffa6c@redhat.com> <830e7c3b-3469-6cea-61d1-5a1e7e230de1@redhat.com> <8DDC5D9D-D601-4D6D-A21F-7A35FF92C6EA@arm.com> Cc: GDB Patches , nd From: Pedro Alves Message-ID: <3f0332c2-1721-003e-e8a4-1e854f2ff00b@redhat.com> Date: Tue, 30 Oct 2018 16:31:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <8DDC5D9D-D601-4D6D-A21F-7A35FF92C6EA@arm.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-SW-Source: 2018-10/txt/msg00713.txt.bz2 On 10/30/2018 11:13 AM, Alan Hayward wrote: >> On 29 Oct 2018, at 18:13, Pedro Alves wrote: >> >> On 10/29/2018 02:56 PM, Alan Hayward wrote: >> >>> A-ha! Now I understand why I get two calls into _push_dummy_call. >>> >>> So to answer your question, the TYPE_CODE_PTR->TYPE_CODE_INT is the malloc call. >>> >>> Then the next call to _push_dummy_call has a return type of 0, as expected. >>> This doesn’t segfault because it goes into language_pass_by_reference which >>> routes to default_pass_by_reference. The same as the C shared library version. >>> >>> >>> I’ve updated the test so it does {c,c++}*{debug nodebug}. >>> I can also update it to do both shared lib and non shared lib too. That should >>> cover everything. >> But still, why do you see a difference between shared library and non-shared >> library? > > In all cases the function type is the same. > > The difference is because with c++ && shared library, the code ends up in > gnuv3_pass_by_reference(), which means it’s using the GNU G++ Version 3 ABI, > whereas with any other options (non shared or c) it ends up in > default_pass_by_reference(). The function is the same, and should have been compiled using the calling convention irrespective of whether it is linked into the main program, or linked into the separate library. Right? So, either I'm missing something, or in one of the cases (shared vs non-shared), we're calling the function incorrectly (along with anything else that depends on call ABI), no? What am I missing? What does: (gdb) show cp-abi The currently selected C++ ABI is "auto" (currently "gnu-v3"). show for you, in the shared and non-shared cases? /me pokes a bit. OK, I see what it is. You've compiled the _main_ .cc without debug info as well: g++ -c condbreak-solib-main.cc -o condbreak-solib-main.o -fno-inline g++ -c condbreak-solib-lib.cc -o condbreak-solib-lib.o -fno-inline g++ condbreak-solib-main.o condbreak-solib-lib.o And if you do that, the program ends up with no debug info at all, and so GDB has no clue that this is a C++ program: (gdb) start Temporary breakpoint 1 at 0x4004c1 Starting program: /tmp/a.out Temporary breakpoint 1, 0x00000000004004c1 in main () (gdb) show language The current source language is "auto; currently c". (gdb) If you compile (only) the main.cc with debug info, like this: - g++ -c condbreak-solib-main.cc -o condbreak-solib-main.o -fno-inline + g++ -c condbreak-solib-main.cc -o condbreak-solib-main.o -fno-inline -g then GDB will know that the program is a C++ program. And you'd still be calling a cmp3 function that has no debug info, and should thus trigger the bug. So when we call cmp3 with GDB's language set to C, we land in default_pass_by_reference: (gdb) show language The current source language is "auto; currently c". (gdb) p (int) cmp3(word) Thread 1 "gdb" hit Breakpoint 3, default_pass_by_reference (type=0x1b5a230) at src/gdb/language.c:669 669 return 0; (top-gdb) c Continuing. When the language is set to C++, we end up in gnuv3_pass_by_reference: (gdb) set language c++ (gdb) p (int) cmp3(word) Thread 1 "gdb" hit Breakpoint 4, gnuv3_pass_by_reference (type=0x1b33290) at src/gdb/gnu-v3-abi.c:1255 1255 type = check_typedef (type); (top-gdb) And this is because language_pass_by_reference uses the current language, instead of the symbol's language (arguably a bug): (top-gdb) bt #0 0x000000000065be91 in gnuv3_pass_by_reference(type*) (type=0x1b33290) at src/gdb/gnu-v3-abi.c:1255 #1 0x0000000000543e2a in cp_pass_by_reference(type*) (type=0x1b33290) at src/gdb/cp-abi.c:229 #2 0x00000000006cc09b in language_pass_by_reference(type*) (type=0x1b33290) at src/gdb/language.c:660 #3 0x000000000045a27a in default_return_in_first_hidden_param_p(gdbarch*, type*) (gdbarch=0x1b316b0, type=0x1b33290) at src/gdb/arch-utils.c:861 #4 0x0000000000640a86 in gdbarch_return_in_first_hidden_param_p(gdbarch*, type*) (gdbarch=0x1b316b0, type=0x1b33290) at src/gdb/gdbarch.c:2739 #5 0x00000000006a1011 in call_function_by_hand_dummy(value*, type*, int, value**, void (*)(void*, int), void*) (function=0x1b44730, default_return_type=0x1b33290, nargs=1, args=0x7fffffffc128, dummy_dtor=0x0, dummy_dtor_data=0x0) at src/gdb/infcall.c:881 So that's the real difference. Shared vs non-shared is just a kind of a red herring. If you don't have debug info for libstdc++, for example, then probably GDB won't know that the no-debug-info program is a C++ program either. So please adjust your test to eliminate use of the shared library, and build just the cmp3 source file without debug info. > Looking at the doc for GNU G++ Version 3 ABI: > https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html > The library needs to be linked against libstdc++.so to use it. > > A quick ldd shows only the c++ .so is linked against it. That wouldn't make much sense. The whole program is using the same compiler/call/mangling ABI, certainly, which is what matters here. Thanks, Pedro Alves