From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23539 invoked by alias); 25 Nov 2014 15:00:05 -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 23512 invoked by uid 89); 25 Nov 2014 15:00:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,SPF_PASS,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mail-oi0-f47.google.com Received: from mail-oi0-f47.google.com (HELO mail-oi0-f47.google.com) (209.85.218.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 25 Nov 2014 15:00:03 +0000 Received: by mail-oi0-f47.google.com with SMTP id v63so516051oia.6 for ; Tue, 25 Nov 2014 07:00:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=Ck9qcZsopMxGC9TM8nx9w56NdTb593mUL3SIQ5doiWo=; b=k3jYEjuj1o7j1qSBfCEos4JjAYdT4YmKdjG1V2bbfj3TqbcFxTcQwfz+AoUB+WT+Ua oDb90plM/eaPEnr4/MfmXxfOyGRQIxS5Xj5Uubg3ja0m2458PDb5+jas7zLUYX8Fu5JY Fp4tWhKjJt4MXAglikNHhlNHgRvxw8G8yUPIiCZEJyr5M5EZIphsa0JqwTWNGtBPGaOk iEUjyVuFBAD6XnJGHMO5bhM7ti1shvEayt+urbCi7wEdNvLR37iRc3TKwv0IxYKmXAxp HSm7b2yZUOyuQH29tZO6TjpZ8N7JgeRDJTh+IZZr8j7jwQlqnqDnzHn5anD/oQdG5Tzs cpOQ== X-Gm-Message-State: ALoCoQnHc/O22qVESgbMCjpDwxpPbctWCSSx8SBpQ56M6u8g4TRg0Ub5F+MoYg1B3bVQ5ei/9eKK MIME-Version: 1.0 X-Received: by 10.202.135.131 with SMTP id j125mr4911607oid.45.1416927601142; Tue, 25 Nov 2014 07:00:01 -0800 (PST) Received: by 10.202.225.68 with HTTP; Tue, 25 Nov 2014 07:00:00 -0800 (PST) In-Reply-To: References: Date: Tue, 25 Nov 2014 15:00:00 -0000 Message-ID: Subject: Re: [RFC] While processing a struct die, store the method's address in its fn_field From: Siva Chandra To: Doug Evans Cc: gdb-patches Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2014-11/txt/msg00625.txt.bz2 On Mon, Nov 24, 2014 at 12:22 PM, Doug Evans wrote: > Adding new fields to types or symbols is a big deal. > I'd like to understand why things are failing better. > For normal functions gdb gets the start address > from BLOCK_START (SYMBOL_BLOCK_VALUE (sym)). I will try, but tl;dr. Consider a simple class definition like this which has a method which is not inlined: class A { public: int method (int a); }; int A::method (int a) { return a * a; } The DWARF for the class comes out like this: < 1><0x0000002d> DW_TAG_class_type DW_AT_name "A" DW_AT_byte_size 0x00000001 DW_AT_decl_file 0x00000001 /tmp DW_AT_decl_line 0x00000001 DW_AT_sibling <0x00000057> < 2><0x00000037> DW_TAG_subprogram DW_AT_external yes(1) DW_AT_name "method" DW_AT_decl_file 0x00000001 /tmp DW_AT_decl_line 0x00000004 DW_AT_linkage_name "_ZN1A6methodEi" DW_AT_type <0x00000057> DW_AT_accessibility DW_ACCESS_public DW_AT_declaration yes(1) DW_AT_object_pointer <0x0000004b> < 3><0x0000004b> DW_TAG_formal_parameter DW_AT_type <0x0000005e> DW_AT_artificial yes(1) < 3><0x00000050> DW_TAG_formal_parameter DW_AT_type <0x00000057> Notice that there is a linkage name for the method named "method". So, one can demangle the linkage name and get to the symbol. If this fails, one can use the linkage name to get to the minsym. The issue with lambdas is that their operator() methods do not have a linkage name. Not exactly true: they have a linkage name but the DWARF doesn't specify it. Consider this example: $> cat lambda.cc int main () { auto lambda = [] (int j) { return j + 113; }; return lambda (-113); } $> g++ -g -std=c++11 lambda.cc -o lambda The DWARF for the lambda struct come out like this: < 3><0x00000070> DW_TAG_structure_type DW_AT_name "" DW_AT_byte_size 0x00000001 DW_AT_decl_file 0x00000001 /tmp DW_AT_decl_line 0x00000004 < 4><0x00000078> DW_TAG_subprogram DW_AT_name "" DW_AT_artificial yes(1) DW_AT_declaration yes(1) DW_AT_object_pointer <0x00000085> DW_AT_sibling <0x0000009c> < 5><0x00000085> DW_TAG_formal_parameter DW_AT_type <0x0000008a> DW_AT_artificial yes(1) < 5><0x0000008a> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x00000070> < 5><0x00000090> DW_TAG_formal_parameter DW_AT_type <0x00000095> < 5><0x00000095> DW_TAG_rvalue_reference_type DW_AT_byte_size 0x00000008 DW_AT_type <0x00000070> < 4><0x0000009c> DW_TAG_subprogram DW_AT_name "" DW_AT_artificial yes(1) DW_AT_declaration yes(1) DW_AT_object_pointer <0x000000a9> DW_AT_sibling <0x000000bf> < 5><0x000000a9> DW_TAG_formal_parameter DW_AT_type <0x0000008a> DW_AT_artificial yes(1) < 5><0x000000ae> DW_TAG_formal_parameter DW_AT_type <0x000000b3> < 5><0x000000b3> DW_TAG_reference_type DW_AT_byte_size 0x00000008 DW_AT_type <0x000000b9> < 5><0x000000b9> DW_TAG_const_type DW_AT_type <0x00000070> < 4><0x000000bf> DW_TAG_subprogram DW_AT_name "" DW_AT_artificial yes(1) DW_AT_declaration yes(1) yes(1) DW_AT_object_pointer <0x000000cc> DW_AT_sibling <0x000000d2> < 5><0x000000cc> DW_TAG_formal_parameter DW_AT_type <0x0000008a> DW_AT_artificial yes(1) < 4><0x000000d2> DW_TAG_subprogram DW_AT_name "~" DW_AT_artificial yes(1) DW_AT_declaration yes(1) DW_AT_object_pointer <0x000000df> DW_AT_sibling <0x000000ea> < 5><0x000000df> DW_TAG_formal_parameter DW_AT_type <0x0000008a> DW_AT_artificial yes(1) < 5><0x000000e4> DW_TAG_formal_parameter DW_AT_type <0x0000002d> DW_AT_artificial yes(1) < 4><0x000000ea> DW_TAG_subprogram DW_AT_name "operator()" DW_AT_type <0x0000002d> DW_AT_artificial yes(1) DW_AT_low_pc 0x00400566 DW_AT_high_pc 19 DW_AT_frame_base len 0x0001: 9c: DW_OP_call_frame_cfa DW_AT_object_pointer <0x0000010f> DW_AT_GNU_all_call_sites yes(1) < 5><0x00000109> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x000000b9> < 5><0x0000010f> DW_TAG_formal_parameter DW_AT_name "__closure" DW_AT_type <0x0000011b> DW_AT_artificial yes(1) DW_AT_location len 0x0002: 9168: DW_OP_fbreg -24 < 5><0x0000011b> DW_TAG_const_type DW_AT_type <0x00000109> < 5><0x00000120> DW_TAG_formal_parameter DW_AT_name "j" DW_AT_decl_file 0x00000001 /tmp DW_AT_decl_line 0x00000004 DW_AT_type <0x0000002d> DW_AT_location len 0x0002: 9164: DW_OP_fbreg -28 Notice that the operator() method has no linkage name specified in the DWARF. But, it has a DW_AT_low_pc. Lets grep the binary for this low pc value: $> readelf -a lambda | grep 400566 41: 0000000000400566 19 FUNC LOCAL DEFAULT 12 _ZZ4mainENKUliE_clEi So then, there is an ELF symbol for the operator() method! Lets demangle the name: (gdb) maintenance demangle _ZZ4mainENKUliE_clEi main::{lambda(int)#1}::operator()(int) const This name is not the same as the name of the lambda structure given by DWARF! If I use clang to compile, the demangled ELF symbol for the operator() turns out to be "main::$_0::operator()(int) const", which seems to indicate that gcc and clang have their own way of differentiating the different lambdas that can occur in a CU. Hence, GDB should probably not even attempt to generate a name, mangle it and lookup for a symbol with that name. However, low_pc is immediately available in the DWARF generated by GCC, so why not use it? [Clang actually does not put out the low pc value for the subprogram die under a structure die, but it puts out a separate (not under a structure die) subprogram die for the operator() method with the low pc value.] Thanks, Siva Chandra