From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by sourceware.org (Postfix) with ESMTPS id 32AA03858D39 for ; Tue, 7 Mar 2023 05:04:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 32AA03858D39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oracle.com Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 326NxQDw008826 for ; Tue, 7 Mar 2023 05:04:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : content-transfer-encoding : content-type : mime-version; s=corp-2022-7-12; bh=ehArcIwzVCRQia9Y+epJg1JqxFwQHUWm2Zz3c7fcV+g=; b=xsB5EkspTJCfwK/0zlBC23PQGdkdrlsBuyIyKm0gscOLOoqetu8iWO3PNnfmQsN7+oHB A5I/nJunSTONJhsBKyhTtMChtdJaT/R4wuEKCApXLBz8iRSIyRrq/XRuqXX7EasD3OrR LX+YzbhEyy6yuhk5rYBx2P7qHi5PzVBrkgppf0VDkQhHSEYyqg6sin8qE7c61LDB/AUe aE6Ikg0tGvV1jy/E73yXxjF5qOhsPo/d4djlYgvyDtVRx9la1D4yLFZ9Y0FzSC3gfB/B gW+lSpiGWmDYeCxs51CSc/1Sp348wIfpVBAdWQk8/ZohU4YKtY8oFCCIcsamO5KM8j0B wQ== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3p4168mmdj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 07 Mar 2023 05:04:42 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 3274h29i008836 for ; Tue, 7 Mar 2023 05:04:41 GMT Received: from nam11-co1-obe.outbound.protection.outlook.com (mail-co1nam11lp2170.outbound.protection.outlook.com [104.47.56.170]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3p4u2h877k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 07 Mar 2023 05:04:41 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=f8pZZfyKKX8NadAx7yYAlowydBEUrSkkiYGptkz1CkUSjNLoDTu8tEYB5a2wG7+g4Lf283rT73vgkGha21lLx7sh4nNnzPLjx3H6aHC0P7b4HS+zBTAb/kIpD3NKbesGApOQxTOu640FXZiuVTfFr3cEZI5dhzKGLlndPWYOS3TPdogfsrFl8auw9rmbzr8qzMrneDAlt8xcFtcq+SeJAznt2sIHETXnL8buo/jgS/pVvbXPlH20BKdfvuUTcUYeNxENAhH3DfviqeOMIiaMnhWC7yKREDtUJiXqVYOqWwb8ds5HW0FcGfo3gQSW/P1VzBxUCiUlgTO7nEH94doqGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ehArcIwzVCRQia9Y+epJg1JqxFwQHUWm2Zz3c7fcV+g=; b=RmmTsVXNLtCk2wAuBsROb5hjOobQM6C3KSHDkvQwfSFSBNwZyvr2TYAt6gWMvb7ESG+dBjFpyrllVNOvhVcJyzftpzwx8qlI/DxrAICkirAvYz7wSZMaqhCKSSIRExpjh7GJXjBaQTt6Bl99r9FbhFxuK+p+SPUML2uWvvakKAiuioRvkf5gxFzqlwivgtb3DqrHFVSSVBLu50F9DtdndnxJ7T1A7AALkdQ25JlyEGwnSsITSGFXW3N0BDkXOg/DicTfDS+ygyqX0xeoAaOSxQGN/BuzRyGibNk+ZtwTUneAF5fEDe7yPZ7jJsspypcZTTf38eeT2Etc7oq+B3rYjA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ehArcIwzVCRQia9Y+epJg1JqxFwQHUWm2Zz3c7fcV+g=; b=Ubi4Dp+zCRYGhYcPJqhoPDRareuItl0kcPkQ08hlPkSDWdAvRoYFcQaHEEIefM4yDHTkclZ73dLezRfXJcTG0hcQ8KsVFeIYY73CrrPk1iQfZwOmEIFyYm2qicM6gS2NJ6DS08AI5ZIc9un11Lxk54Fq64BAMDL3i5p66MnhfGo= Received: from SA2PR10MB4636.namprd10.prod.outlook.com (2603:10b6:806:11e::10) by DM4PR10MB6133.namprd10.prod.outlook.com (2603:10b6:8:b4::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6156.28; Tue, 7 Mar 2023 05:04:38 +0000 Received: from SA2PR10MB4636.namprd10.prod.outlook.com ([fe80::534c:a39:4701:8319]) by SA2PR10MB4636.namprd10.prod.outlook.com ([fe80::534c:a39:4701:8319%6]) with mapi id 15.20.6156.029; Tue, 7 Mar 2023 05:04:38 +0000 From: vladimir.mezentsev@oracle.com To: binutils@sourceware.org Cc: Vladimir Mezentsev Subject: [Review is needed] gprofng: read Dwarf 5 Date: Mon, 6 Mar 2023 21:04:31 -0800 Message-Id: <20230307050431.288433-1-vladimir.mezentsev@oracle.com> X-Mailer: git-send-email 2.31.1 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: BYAPR07CA0086.namprd07.prod.outlook.com (2603:10b6:a03:12b::27) To SA2PR10MB4636.namprd10.prod.outlook.com (2603:10b6:806:11e::10) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PR10MB4636:EE_|DM4PR10MB6133:EE_ X-MS-Office365-Filtering-Correlation-Id: 709ec409-d65d-4c79-e827-08db1ec972c9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PxiKvOu2N2Ousmf47Vq3uhe0ssQaHssGSIbD8aAL3bLWcKpE2RlUhRH/E9Ao8iEoyRB49phH8Y838OSDZa3QATMUs/igATKY56PpXRRz4ZsGVDPcaKIw+o9TvaUGqDbKphsHVn/cBhFArqXhhQi0WyKfd+uXLZ1SDiJXMO6xZX5q2G8Y/iA3snb7WBzVxN/DutrB3hS7ioPf02riZn7DnQjbxy7QxfF+iSYnoap8/2vFnAyPe/aZzu4NjzKxiNF65WJdV9Fn/Ls2qTsvijieeIzBLDn3trmQcH3U+gVO6ehfP82/JKlME7vZH/zQoXF5W3Be6ieBtl8S1szTx0NbFuRGt43k+P6pdaLf6qQeZNw5lyzNMZcOpJabdU4dToR/POQzQs24ycWzOODTz2z7Y5GJCMwrDQfNkZo0DFIwmvBJ3rIjgaq60v2OYnVpG4Sj/uUHYxErM3LyBoej9xWvXLumQwz+dEqHPsoj8Ni5JbLj/nL4fLpOn+5/UZMP8ouI2GR9m4msBSoYrLzPQuu4Uv0I6SF2wieOc8DfE9gGImhRdmnuuqpUtllnZQuyWqp6GaiyKUCUA4zZI7WqmgI/n3hy5MKG1Fu6OuxX4s1EebxBtpLS3Rykq6SgK/6dggrxAS7yxQLaE2l1ecTDTR1Juw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA2PR10MB4636.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(366004)(376002)(136003)(346002)(39860400002)(396003)(451199018)(4326008)(36756003)(66946007)(66556008)(6916009)(41300700001)(66476007)(8676002)(8936002)(1076003)(2906002)(5660300002)(30864003)(86362001)(38100700002)(107886003)(6486002)(6666004)(478600001)(316002)(83380400001)(6506007)(2616005)(186003)(9686003)(26005)(6512007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?EcbN+uQBH9eLTgk58fSv5mjr8NU8W9ciidv7tro1BjT30Kpoe0pRpdt6ZjM9?= =?us-ascii?Q?bhK0OZHg4GBIy7v0oy/91lwlhlfwkHuhBv1kTaoHUo0JoBtqgHKk3hTaigpV?= =?us-ascii?Q?HqDd/8KLYpK1SuBSFxgLDZjAX2nz2nh0aX3goR9Br9tz3ojyYuWX+QEjtk4O?= =?us-ascii?Q?7D0IRbdzvD3NjAtGXQHPphQSqCRq9aWkDBroGvl8hV//OZ9iINEc/qMn7+nW?= =?us-ascii?Q?Sbifig9hVplWH35BVaQugmHEcVmZ5DVQ5kHm1hvJZSe8Vs0NAzsyrKH8rviW?= =?us-ascii?Q?fJ2dnhR/eR5Z3gbp1Y9dXdIo5WH4gd1PW/ovF7R7SV/M+sXJxtNiae7sIbOX?= =?us-ascii?Q?SSBI6Vcx2/GaNptBubqo+PJferlrF+gV4jo4esD85JKBM28qJPYPruDL5PxM?= =?us-ascii?Q?zNNMPRDPQKBTEzLZgAI0wmKyWN/ACp24a2Ms8/Ksk1iRaV0b0x8OKV69rbbl?= =?us-ascii?Q?eFOD/F+a5oZsg6dtMmiGAuiz2FcLyGInzBWdBo91XN8G6P5wm2As43VMCy2N?= =?us-ascii?Q?yvcZhVh9Evsthk8MJv2fkyDSXyGR3KD+RoAY0J0qN2lEH0zCzVNqPPrRKvTS?= =?us-ascii?Q?/TezlMUgCzpABSO0/eeMVP5+EN1k7gJ5sschyv1hUf+DjQXp+sHo/GNSP2is?= =?us-ascii?Q?jzZJf9KAMCRZD3gUjr0GAJ9tIrB5qVFIOAlUpzTggzuEO++txBkdSM4+TnCt?= =?us-ascii?Q?uyX9iHTmBD6K6W0c3N2ytPxL4e5bmq8MSoo0RKH2nteZasRxYHD6NqgMaqii?= =?us-ascii?Q?U8/B29Kt15iRXhaeUdEVx6vx7aXDMc3ZclcdVfxAUGV0SDGF4so251f5RtgB?= =?us-ascii?Q?IhYFiNmPQa+HbKBzlQJJNeGKK+03BnB0T9eo/EvYhiwU8BZ2Z/o6PywhIVQ5?= =?us-ascii?Q?SXEzHaoAK2xtd5MhAkjvQujkoKNOGN2ZQ/BjOR3xC1BcEe2XtGOc9brdYRyz?= =?us-ascii?Q?FpsVxCVjSaJnhgX+p4+CtY6HL8TXnHLtlpzi38rlJieTHZ47ULPPeCulWg++?= =?us-ascii?Q?8wJdvW61kFwxop9TBdOQ5M0/VZpaFJMU5XDHpdo9JzTsC/Apse1bj6PR7rTL?= =?us-ascii?Q?kCOEKdgi6avsY/xBjaYbEcWIru5Ffb7nOvfM/38FN27nos+RTOO8nkKZYj+y?= =?us-ascii?Q?f02uZR7vg5k/vtfpvY3uiDurhd02xy9bJHuIoZlRdG6gk9R6oATSfjTa2qu5?= =?us-ascii?Q?D4QOYZMrEc6iXhZHRWyziSZxihcbomoHLCmQsv/z/Afk6eYgTOQK+6YW8zNG?= =?us-ascii?Q?Wn7ltQ3s95jaLoMJ5fVWs3oUgZjYYR1JaljLrdsfur7gYX8uM6JNF5DvebWy?= =?us-ascii?Q?TnL0TQfRKXgAsE6rwYMSflcEq+GAyrdymnJD0MYvwdyELThakv7Aep8bFHTX?= =?us-ascii?Q?2oj+QXbn7yUbsYw99XDuqKI2iqUI0LtaxwOeHB0MmpWH1iTbjtVute4Fu7yd?= =?us-ascii?Q?UGOD0I9izQGCr3AYvSY8GrRALIhrS+dqjiNME8OCcmQev3ImxSJkw4i+Vj7l?= =?us-ascii?Q?F18k/D0f2uh+gDxHz/IctwTOECuIXJSyP6LWtKgdTGlyZpTXP9Wenwkqr+et?= =?us-ascii?Q?YA2fNbjwng2VSCYWfgBKwiPHRc8PbW5Ycdy0qcqZcdryL3suLeiTreGIRFMH?= =?us-ascii?Q?xmyYQrsfjSAcZtosLXRa7V0=3D?= X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: YNOsQ8Yjg2vhsxcJS0DzwWqAbo5vc60Q1slRcxjY+VgMndhQ0fJvi17HfVr2Qau5U0cgqsRMFKw6t0p7nAmqCH0YJYVFfNi39M+B4VnSsV2O8FtGf85/axAFCgAbJtBzHD93j+AcJfok+sXu7qlv4Ib40qMgwvPW6UKAdqu7vxkP6CLY1dewFwR9yiyKkW1XlUKWUMhqG2v8dvfs5KMUVyWBG58OWfG/nhQxKZa6Kz2De79LzjPQY84XKcVuAvzjD85bXGaM7sliJ3iYshkVjwQ9nlL4NpDq37cX4O3ZYWMJF0yWFPuICUgwCn6oRxatljH8M+g5bfoA3XWHz1F7OHR/a+eNGMGBqjkjqyHiMuoUDKWMOxM0PQRmESHnkTGp9EoDV42Gf2zgrLlSVI92uFoye2hpnoMgMe2JDMZWwizMCXv1qaUCDwE56oJ+uYXICbE71SIRKHEpOOb4Klz49T6L0TxZagm7rDbDdbV9cnidbY2lX1msAePmppCjZ4DP9LoKaOGYq0XVa2B+TBaLbpJEdXMviGrJyERzXqWbmKAhJu8RCdP3143NrtTquNJhQB/3FwzlZPSRewLQ/fnLSyUzpXfSY9mlQ8nIWriEWV7tUwX+zXeFraG0JDLrw7q4haVGxGTi6NJ1iPGAWmVY5isu/kgRZwIoKB/tMG0cRp1R89uWzslNIOOx50bkrxeJXWD7cYlMa6QeG62kkWlKf4uM+v0H3AQsa0GYT6r4ckOtKz3KziUHGPOKiv1BMIqq X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 709ec409-d65d-4c79-e827-08db1ec972c9 X-MS-Exchange-CrossTenant-AuthSource: SA2PR10MB4636.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Mar 2023 05:04:38.3518 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: UTeRn5L9B81KXmmVKNgwU2KaUrwGpO74dTofjtQxEtQrx3VvTkLe29D7TRHC6m07gnhUWeXuj/B/MLtLLs239u+DuJAXCKfFGZeCURWa524= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR10MB6133 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-03-06_14,2023-03-06_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 suspectscore=0 bulkscore=0 phishscore=0 spamscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2303070045 X-Proofpoint-GUID: pWhmcJda-a2dmv16QtOO_ABTX6Rce3QW X-Proofpoint-ORIG-GUID: pWhmcJda-a2dmv16QtOO_ABTX6Rce3QW X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_NUMSUBJECT,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Vladimir Mezentsev gprofng reads Dwarf to find function names, sources, and line numbers. gprofng skips other debug information. I fixed three places in gprofng Dwarf reader: - parsing the compilation unit header. - parsing the line number table header. - parsing new DW_FORMs. Tested on aarch64-linux/x86_64-linux. gprofng/ChangeLog 2023-03-05 Vladimir Mezentsev PR gprofng/30195 gprofng/src/Dwarf.cc: Support Dwarf-5. gprofng/src/DwarfLib.cc: Likewise. gprofng/src/Dwarf.h: Likewise. gprofng/src/DwarfLib.h: Likewise. gprofng/src/collctrl.cc: Don't read freed memory. --- gprofng/src/Dwarf.cc | 10 +- gprofng/src/Dwarf.h | 1 + gprofng/src/DwarfLib.cc | 458 +++++++++++++++++++++++++++++++--------- gprofng/src/DwarfLib.h | 14 +- gprofng/src/collctrl.cc | 4 +- 5 files changed, 382 insertions(+), 105 deletions(-) diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index fb430cdb079..c98210284dc 100644 --- a/gprofng/src/Dwarf.cc +++ b/gprofng/src/Dwarf.cc @@ -369,6 +369,7 @@ Dwarf::Dwarf (Stabs *_stabs) debug_abbrevSec = NULL; debug_strSec = NULL; debug_lineSec = NULL; + debug_line_strSec = NULL; debug_rangesSec = NULL; elf = stabs->openElf (true); if (elf == NULL) @@ -388,6 +389,7 @@ Dwarf::Dwarf (Stabs *_stabs) debug_strSec = dwrGetSec (NTXT (".debug_str")); debug_lineSec = dwrGetSec (NTXT (".debug_line")); debug_rangesSec = dwrGetSec (NTXT (".debug_ranges")); + debug_line_strSec = dwrGetSec (".debug_line_str"); if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL)) { @@ -610,9 +612,9 @@ Dwarf::archive_Dwarf (LoadObject *lo) dwrCU->srcFiles = new Vector (VecSize (lineReg->file_names)); for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++) { - char *fname = lineReg->getPath (i + 1); - SourceFile *sf = mod->findSource (fname, true); - dwrCU->srcFiles->append (sf); + char *fname = lineReg->getPath (i); + if (fname) + dwrCU->srcFiles->append (mod->findSource (fname, true)); } } @@ -988,7 +990,7 @@ DwrCU::append_Function (Dwarf_cnt *ctx) if (lineno > 0) { func->setLineFirst (lineno); - int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1; + int fileno = ((int) Dwarf_data (DW_AT_decl_file)); SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) : module->getMainSrc (); func->setDefSrc (sf); diff --git a/gprofng/src/Dwarf.h b/gprofng/src/Dwarf.h index 1d99d78745d..0d7756397c4 100644 --- a/gprofng/src/Dwarf.h +++ b/gprofng/src/Dwarf.h @@ -76,6 +76,7 @@ public: DwrSec *debug_abbrevSec; DwrSec *debug_strSec; DwrSec *debug_lineSec; + DwrSec *debug_line_strSec; DwrSec *debug_rangesSec; Elf *elf; Stabs *stabs; diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc index e7130a7a438..e90c685ebbb 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -140,6 +140,33 @@ template<> void Vector Dprintf (1, NTXT ("\n\n")); } +template<> void Vector +::dump (const char *msg) +{ + Dprintf (1, "\n%s Vector [%lld]: [dir_ind tstamp fsize]\n", + msg ? msg : NTXT (""), (long long) size ()); + for (long i = 0, sz = size (); i < sz; i++) + { + DwrFileName *fnp = get (i); + Dprintf (1, " %2ld %3lld %8lld %8lld %s\n", i, (long long) fnp->dir_index, + (long long) fnp->timestamp, (long long) fnp->file_size, + STR (fnp->fname)); + } + Dprintf (1, "\n"); +} + +static char * +get_string (DwrSec *sec, uint64_t off) +{ + if (sec) + { + sec->offset = off; + return sec->GetString (); + } + return NULL; +} + + ////////////////////////////////////////////////////////// // class ElfReloc @@ -687,6 +714,16 @@ DwrCU::tag2str (int tag) CASE_S (DW_TAG_SUN_memop_info); CASE_S (DW_TAG_hi_user); CASE_S (DW_TAG_icc_compile_unit); + CASE_S (DW_TAG_rvalue_reference_type); + CASE_S (DW_TAG_coarray_type); + CASE_S (DW_TAG_generic_subrange); + CASE_S (DW_TAG_dynamic_type); + CASE_S (DW_TAG_atomic_type); + CASE_S (DW_TAG_call_site); + CASE_S (DW_TAG_call_site_parameter); + CASE_S (DW_TAG_skeleton_unit); + CASE_S (DW_TAG_immutable_type); + CASE_S (0); default: s = NTXT ("???"); break; } @@ -833,6 +870,8 @@ DwrCU::at2str (int tag) CASE_S (DW_AT_GNU_all_tail_call_sites); CASE_S (DW_AT_GNU_all_call_sites); CASE_S (DW_AT_GNU_all_source_call_sites); + CASE_S (DW_AT_GNU_locviews); + CASE_S (DW_AT_GNU_entry_view); CASE_S (DW_AT_SUN_command_line); CASE_S (DW_AT_SUN_func_offsets); CASE_S (DW_AT_SUN_cf_kind); @@ -846,6 +885,36 @@ DwrCU::at2str (int tag) CASE_S (DW_AT_SUN_link_name); CASE_S (DW_AT_hi_user); CASE_S (DW_AT_icc_flags); + CASE_S (DW_AT_string_length_bit_size); + CASE_S (DW_AT_string_length_byte_size); + CASE_S (DW_AT_rank); + CASE_S (DW_AT_str_offsets_base); + CASE_S (DW_AT_addr_base); + CASE_S (DW_AT_rnglists_base); + CASE_S (DW_AT_dwo_name); + CASE_S (DW_AT_reference); + CASE_S (DW_AT_rvalue_reference); + CASE_S (DW_AT_macros); + CASE_S (DW_AT_call_all_calls); + CASE_S (DW_AT_call_all_source_calls); + CASE_S (DW_AT_call_all_tail_calls); + CASE_S (DW_AT_call_return_pc); + CASE_S (DW_AT_call_value); + CASE_S (DW_AT_call_origin); + CASE_S (DW_AT_call_parameter); + CASE_S (DW_AT_call_pc); + CASE_S (DW_AT_call_tail_call); + CASE_S (DW_AT_call_target); + CASE_S (DW_AT_call_target_clobbered); + CASE_S (DW_AT_call_data_location); + CASE_S (DW_AT_call_data_value); + CASE_S (DW_AT_noreturn); + CASE_S (DW_AT_alignment); + CASE_S (DW_AT_export_symbols); + CASE_S (DW_AT_deleted); + CASE_S (DW_AT_defaulted); + CASE_S (DW_AT_loclists_base); + default: s = NTXT ("???"); break; } @@ -867,6 +936,9 @@ DwrCU::form2str (int tag) CASE_S (DW_FORM_data2); CASE_S (DW_FORM_data4); CASE_S (DW_FORM_data8); + CASE_S (DW_FORM_data16); + CASE_S (DW_FORM_line_strp); + CASE_S (DW_FORM_implicit_const); CASE_S (DW_FORM_string); CASE_S (DW_FORM_block); CASE_S (DW_FORM_block1); @@ -894,6 +966,28 @@ DwrCU::form2str (int tag) return buf; } +char * +DwrCU::lnct2str (int ty) +{ + static char buf[128]; + char *s; + switch (ty) + { + CASE_S (DW_LNCT_path); + CASE_S (DW_LNCT_directory_index); + CASE_S (DW_LNCT_timestamp); + CASE_S (DW_LNCT_size); + CASE_S (DW_LNCT_MD5); + CASE_S (DW_LNCT_lo_user); + CASE_S (DW_LNCT_hi_user); + default: s = NTXT ("???"); + break; + } + snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, ty); + buf[sizeof (buf) - 1] = 0; + return buf; +} + void Dwr_Tag::dump () { @@ -910,14 +1004,16 @@ Dwr_Tag::dump () { case DW_FORM_strp: case DW_FORM_string: - Dprintf (DUMP_DWARFLIB, " \"%s\" len=%ld", - atrp->u.str ? atrp->u.str : NTXT (""), - (long) atrp->len); + case DW_FORM_line_strp: + case DW_FORM_strp_sup: + case DW_FORM_implicit_const: + Dprintf (DUMP_DWARFLIB, " \"%s\"", atrp->u.str ? atrp->u.str : ""); break; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: + case DW_FORM_data16: Dprintf (DUMP_DWARFLIB, " len=%3ld %p", (long) atrp->len, atrp->u.str); break; @@ -1041,6 +1137,19 @@ DwrSec::Get_16 () return n; } +uint32_t +DwrSec::Get_24 () +{ + uint32_t n = 0; + if (bounds_violation (3)) + return n; + memcpy ((char *) &n, data + offset, 3); + offset += 3; + if (need_swap_endian) + SWAP_ENDIAN (n); + return n; +} + uint32_t DwrSec::Get_32 () { @@ -1078,27 +1187,17 @@ DwrSec::GetData (uint64_t len) } char * -DwrSec::GetString (uint64_t *lenp) -{ - if (offset < size) - { - uint64_t len = 0; - for (char *s = ((char *) data) + offset; offset + len < size; len++) - { - if (s[len] == 0) - { // '\0' is inside section - offset += len + 1; - if (len == 0) - return NULL; - if (lenp) - *lenp = len + 1; - return s; - } - } - offset += len; - return NULL; // The section is not '\0' terminated - } - return NULL; +DwrSec::GetString () +{ + uint64_t off = offset; + while (offset < size) + if (data[offset++] == 0) + { // '\0' is inside section + if (off + 1 == offset) + return NULL; + return ((char *) data) + off; + } + return NULL; // The section is not '\0' terminated } uint64_t @@ -1173,6 +1272,37 @@ DwrSec::GetSLEB128 () return (SLEB128) res; } +uint64_t +DwrSec::get_value (int dw_form) +{ + uint64_t v; + switch (dw_form) + { + case DW_FORM_line_strp: + case DW_FORM_strp: + case DW_FORM_strp_sup: + return GetRef (); + case DW_FORM_data1: + return Get_8 (); + case DW_FORM_data2: + return Get_16 (); + case DW_FORM_data4: + return Get_32 (); + case DW_FORM_data8: + return Get_64 (); + case DW_FORM_udata: + return GetULEB128 (); + case DW_FORM_data16: + offset += 16; + return offset - 16; + case DW_FORM_block: + v = GetULEB128 (); + offset += v; + return offset - v; + } + return 0; +} + static void fillBuf (unsigned char *s, int len, int col, unsigned char *buf) { @@ -1229,7 +1359,7 @@ DwrSec::dump (char *msg) DwrFileName::DwrFileName (char *_fname) { path = NULL; - fname = _fname; + fname = dbe_strdup (_fname); dir_index = 0; timestamp = 0; file_size = 0; @@ -1267,8 +1397,13 @@ LineRegsCmp (const void *a, const void *b) item1->address > item2->address ? 1 : -1; } -DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName) +DwrLineRegs::DwrLineRegs (Dwarf *_dwarf, DwrSec *secp, char *dirName) { + dwarf = _dwarf; + dir_names = NULL; + file_names = NULL; + lines = NULL; + fname = NULL; // `dwarfdump -vv -l` shows a line section (.debug_line) debug_lineSec = secp; uint64_t stmt_offset = debug_lineSec->offset; @@ -1276,11 +1411,16 @@ DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName) uint64_t header_offset = debug_lineSec->offset; debug_lineSec->size = next_cu_offset; version = debug_lineSec->Get_16 (); + if (version == 5) + { + debug_lineSec->address_size = debug_lineSec->Get_8(); + debug_lineSec->segment_selector_size = debug_lineSec->Get_8(); + } header_length = debug_lineSec->GetLong (); opcode_start = debug_lineSec->offset + header_length; minimum_instruction_length = debug_lineSec->Get_8 (); op_index_register = 0; - if (version == 4) + if (version >= 4) maximum_operations_per_instruction = debug_lineSec->Get_8 (); else maximum_operations_per_instruction = 1; @@ -1295,9 +1435,9 @@ DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName) { Dprintf (DUMP_DWR_LINE_REGS, "\n.debug_line version=%d stmt_offset=0x%llx" - "header_offset=0x%llx size=%lld dirname='%s'\n" + " header_offset=0x%llx size=%lld dirname='%s'\n" " header_length=0x%llx opcode_start=0x%llx" - "minimum_instruction_length=%d default_is_stmt=%d\n" + " minimum_instruction_length=%d default_is_stmt=%d\n" " line_base=%d line_range=%d opcode_base=%d\n", (int) version, (long long) stmt_offset, (long long) header_offset, @@ -1313,40 +1453,122 @@ DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName) (int) standard_opcode_length[i]); } - include_directories = new Vector; - include_directories->append (dirName); - while (true) + if (version == 5) { - char *s = debug_lineSec->GetString (NULL); - if (s == NULL) - break; - include_directories->append (s); + dir_names = read_file_names_dwarf5 (); + file_names = read_file_names_dwarf5 (); } - - file_names = new Vector; - while (true) + else { - char *s = debug_lineSec->GetString (NULL); - if (s == NULL) - break; - DwrFileName *fnp = new DwrFileName (s); - fnp->path = NULL; - fnp->fname = s; - fnp->dir_index = debug_lineSec->GetULEB128_32 (); - fnp->timestamp = debug_lineSec->GetULEB128 (); - fnp->file_size = debug_lineSec->GetULEB128 (); - file_names->append (fnp); + dir_names = new Vector; + dir_names->append (new DwrFileName (dirName)); + while (true) + { + char *s = debug_lineSec->GetString (); + if (s == NULL) + break; + dir_names->append (new DwrFileName (s)); + } + + file_names = new Vector; + file_names->append (new DwrFileName (dirName)); + while (true) + { + char *s = debug_lineSec->GetString (); + if (s == NULL) + break; + DwrFileName *fnp = new DwrFileName (s); + fnp->dir_index = debug_lineSec->GetULEB128_32 (); + fnp->timestamp = debug_lineSec->GetULEB128 (); + fnp->file_size = debug_lineSec->GetULEB128 (); + file_names->append (fnp); + } } - lines = NULL; dump (); } DwrLineRegs::~DwrLineRegs () { + Destroy (dir_names); Destroy (file_names); Destroy (lines); delete debug_lineSec; - delete include_directories; +} + +Vector * +DwrLineRegs::read_file_names_dwarf5 () +{ + + typedef struct + { + int type_code; + int form_code; + } t_entry_fmt; + + int efmt_cnt = debug_lineSec->Get_8 (); + Dprintf (DUMP_DWR_LINE_REGS, "\nRead names: offset=0x%llx entry_fmt_cnt=%d\n", + (long long) debug_lineSec->offset, efmt_cnt); + if (efmt_cnt == 0) + return NULL; + t_entry_fmt *efmt = (t_entry_fmt *) malloc (sizeof (t_entry_fmt) * efmt_cnt); + for (int i = 0; i < efmt_cnt; i++) + { + efmt[i].type_code = debug_lineSec->GetULEB128 (); + efmt[i].form_code = debug_lineSec->GetULEB128 (); + Dprintf (DUMP_DWR_LINE_REGS, " %2d %20s %s\n", i, + DwrCU::lnct2str (efmt[i].type_code), + DwrCU::form2str (efmt[i].form_code)); + } + + int cnt = debug_lineSec->GetULEB128_32 (); + Dprintf (DUMP_DWR_LINE_REGS, "\nRead names: offset=0x%llx names_cnt=%d\n", + (long long) debug_lineSec->offset, cnt); + Vector *fnames = new Vector (cnt); + for (int i = 0; i < cnt; i++) + { + int ind = 0; + uint64_t off = 0; + uint64_t tstamp = 0; + uint64_t fsize = 0; + char *nm = NULL; + for (int k = 0; k < efmt_cnt; k++) + switch (efmt[k].type_code) + { + case DW_LNCT_path: + if (efmt[k].form_code == DW_FORM_string) + nm = debug_lineSec->GetString (); + else + { + off = debug_lineSec->get_value (efmt[k].form_code); + if (efmt[k].form_code == DW_FORM_line_strp) + nm = get_string (dwarf->debug_line_strSec, off); + else if (efmt[k].form_code == DW_FORM_strp) + nm = get_string (dwarf->debug_strSec, off); + } + break; + case DW_LNCT_directory_index: + ind = debug_lineSec->get_value (efmt[k].form_code); + break; + case DW_LNCT_timestamp: + tstamp = debug_lineSec->get_value (efmt[k].form_code); + break; + case DW_LNCT_size: + fsize = debug_lineSec->get_value (efmt[k].form_code); + break; + case DW_LNCT_MD5: + (void) debug_lineSec->get_value (efmt[k].form_code); + break; + } + Dprintf (DUMP_DWR_LINE_REGS, " %3d ind=%d off=0x%08llx %s\n", + i, ind, (long long) off, STR (nm)); + DwrFileName *fnp = new DwrFileName (nm); + fnp->dir_index = ind; + fnp->timestamp = tstamp; + fnp->file_size = fsize; + fnames->append (fnp); + } + free (efmt); + return fnames; } void @@ -1354,12 +1576,10 @@ DwrLineRegs::dump () { if (!DUMP_DWR_LINE_REGS) return; - Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\ninclude_directories size=%lld\n"), (long long) VecSize (include_directories)); - for (long i = 0, sz = VecSize (include_directories); i < sz; i++) - { - char *s = include_directories->get (i); - Dprintf (DUMP_DWR_LINE_REGS, NTXT (" %2lld %s\n"), (long long) i, STR (s)); - } + if (dir_names) + dir_names->dump ("dir_names"); + if (file_names) + file_names->dump ("file_names"); Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\nfile_names size=%lld\n"), (long long) VecSize (file_names)); for (long i = 0, sz = VecSize (file_names); i < sz; i++) @@ -1396,7 +1616,7 @@ DwrLineRegs::DoExtendedOpcode () break; case DW_LNE_define_file: // TODO, add file to file list - fname = debug_lineSec->GetString (NULL); + fname = debug_lineSec->GetString (); dir_index = debug_lineSec->GetULEB128 (); timestamp = debug_lineSec->GetULEB128 (); file_size = debug_lineSec->GetULEB128 (); @@ -1467,7 +1687,7 @@ DwrLineRegs::reset () timestamp = 0; file_size = 0; address = 0; - file = 1; + file = 0; line = 1; column = 0; is_stmt = (default_is_stmt != 0); @@ -1535,39 +1755,31 @@ DwrLineRegs::get_lines () char * DwrLineRegs::getPath (int fn) { - fn--; - if ((fn >= VecSize (file_names)) || (fn < 0)) + if (fn >= VecSize (file_names) || fn < 0) { Dprintf (DEBUG_ERR_MSG, NTXT ("DwrLineRegs::getPath: fn=0x%lld file_names->size()=%lld\n"), (long long) fn, (long long) VecSize (file_names)); return NULL; } DwrFileName *fnp = file_names->fetch (fn); + if (fnp->fname == NULL) + return NULL; if (fnp->path) return fnp->path; - char *dir = fnp->dir_index < include_directories->size () ? - include_directories->fetch (fnp->dir_index) : NULL; - if ((fnp->fname[0] == '/') || (dir == NULL) || (*dir == 0)) - { - fnp->path = fnp->fname; - return fnp->path; - } + fnp->path = fnp->fname; + if (fnp->fname[0] == '/') + return fnp->path; - StringBuilder sb; - if (*dir != '/') - { // not absolute - char *s = include_directories->fetch (0); - if (s != NULL && *s != 0) - { - sb.append (s); - sb.append ('/'); - } + char *dir = NULL; + if (dir_names) + { + if (fnp->dir_index < dir_names->size () && fnp->dir_index >= 0) + dir = dir_names->get (fnp->dir_index)->fname; } - sb.append (dir); - sb.append ('/'); - sb.append (fnp->fname); - fnp->path = canonical_path (sb.toString ()); + if (dir == NULL || *dir == 0) + return fnp->path; + fnp->path = canonical_path (dbe_sprintf ("%s/%s", dir, fnp->fname)); return fnp->path; } @@ -1586,8 +1798,18 @@ DwrCU::DwrCU (Dwarf *_dwarf) } debug_infoSec->size = next_cu_offset; version = debug_infoSec->Get_16 (); - debug_abbrev_offset = debug_infoSec->GetLong (); - address_size = debug_infoSec->Get_8 (); + if (version == 5) + { + unit_type = debug_infoSec->Get_8 (); + address_size = debug_infoSec->Get_8 (); + debug_abbrev_offset = debug_infoSec->GetLong (); + } + else + { + unit_type = DW_UT_compile; + debug_abbrev_offset = debug_infoSec->GetLong (); + address_size = debug_infoSec->Get_8 (); + } cu_header_offset = debug_infoSec->offset; comp_dir = NULL; module = NULL; @@ -1606,7 +1828,7 @@ DwrCU::DwrCU (Dwarf *_dwarf) { Dprintf (DUMP_DWARFLIB, "CU_HEADER: header_offset = 0x%08llx %lld" - "next_header_offset=0x%08llx %lld\n" + " next_header_offset=0x%08llx %lld\n" " abbrev_offset = 0x%08llx %lld\n" " unit_length = %lld\n" " version = %d\n" @@ -1685,10 +1907,18 @@ DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset) while (debug_abbrevSec->offset < debug_abbrevSec->size) { Dwr_Attr atf; + atf.len = 0; + atf.u.str = NULL; atf.at_name = debug_abbrevSec->GetULEB128_32 (); atf.at_form = debug_abbrevSec->GetULEB128_32 (); if (atf.at_name == 0 && atf.at_form == 0) break; + switch (atf.at_form) + { + case DW_FORM_implicit_const: + atf.len = debug_abbrevSec->GetSLEB128 (); + break; + } abbrevAtForm->append (atf); } abbTbl.lastAtForm = abbrevAtForm->size (); @@ -1782,20 +2012,12 @@ DwrCU::set_die (Dwarf_Die die) atf->u.offset = debug_infoSec->Get_64 (); break; case DW_FORM_string: - atf->u.str = debug_infoSec->GetString (&atf->len); + atf->u.offset = debug_infoSec->offset; + atf->u.str = debug_infoSec->GetString (); break; case DW_FORM_strp: atf->u.offset = debug_infoSec->GetRef (); - if (dwarf->debug_strSec == NULL) - { - atf->u.str = NULL; - atf->len = 0; - } - else - { - dwarf->debug_strSec->offset = atf->u.offset; - atf->u.str = dwarf->debug_strSec->GetString (&atf->len); - } + atf->u.str = get_string (dwarf->debug_strSec, atf->u.offset); break; case DW_FORM_sdata: atf->u.val = debug_infoSec->GetSLEB128 (); @@ -1819,6 +2041,49 @@ DwrCU::set_die (Dwarf_Die die) case DW_FORM_ref_sig8: atf->u.offset = debug_infoSec->GetADDR_64 (); break; + case DW_FORM_data16: // we never use this data. Skip 16 bytes + atf->len = 16; + (void) debug_infoSec->Get_64 (); + (void) debug_infoSec->Get_64 (); + break; + case DW_FORM_addrx: + case DW_FORM_strx: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: + atf->u.offset = debug_infoSec->GetULEB128 (); + break; + case DW_FORM_addrx1: + case DW_FORM_strx1: + atf->u.offset = debug_infoSec->Get_8 (); + break; + case DW_FORM_addrx2: + case DW_FORM_strx2: + atf->u.offset = debug_infoSec->Get_16 (); + break; + case DW_FORM_addrx3: + case DW_FORM_strx3: + atf->u.offset = debug_infoSec->Get_24 (); + break; + case DW_FORM_addrx4: + case DW_FORM_strx4: + case DW_FORM_ref_sup4: + atf->u.offset = debug_infoSec->Get_32 (); + break; + case DW_FORM_ref_sup8: + atf->u.offset = debug_infoSec->Get_64 (); + break; + case DW_FORM_line_strp: + atf->u.offset = debug_infoSec->GetRef (); + atf->u.str = get_string (dwarf->debug_line_strSec, atf->u.offset); + break; + case DW_FORM_strp_sup: + atf->u.offset = debug_infoSec->GetRef (); + atf->u.str = NULL; + atf->len = 0; + break; + case DW_FORM_implicit_const: + atf->u.str = NULL; + break; default: DEBUG_CODE { @@ -1974,6 +2239,7 @@ DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal) case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: + case DW_FORM_data16: case DW_FORM_udata: case DW_FORM_sec_offset: *retVal = dwrAttr->u.val; @@ -2132,7 +2398,7 @@ DwrLineRegs * DwrCU::get_dwrLineReg () { if (dwrLineReg == NULL && stmt_list_offset != NO_STMT_LIST) - dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec, + dwrLineReg = new DwrLineRegs (dwarf, new DwrSec (dwarf->debug_lineSec, stmt_list_offset), comp_dir); return dwrLineReg; } diff --git a/gprofng/src/DwarfLib.h b/gprofng/src/DwarfLib.h index d359c7583b1..6baecac3a1b 100644 --- a/gprofng/src/DwarfLib.h +++ b/gprofng/src/DwarfLib.h @@ -61,8 +61,10 @@ public: uint64_t ReadLength (); SLEB128 GetSLEB128 (); ULEB128 GetULEB128 (); - char *GetString (uint64_t *lenp); + char *GetString (); char *GetData (uint64_t len); + uint32_t Get_24 (); + uint64_t get_value (int dw_form); void dump (char *msg); inline uint32_t @@ -84,6 +86,8 @@ public: bool fmt64; bool addr32; bool need_swap_endian; + int address_size; + int segment_selector_size; // DWARF 5 private: bool isCopy; @@ -132,7 +136,7 @@ public: class DwrLineRegs { public: - DwrLineRegs (DwrSec *_secp, char *dirName); + DwrLineRegs (Dwarf *_dwarf, DwrSec *_secp, char *dirName); ~DwrLineRegs (); char *getPath (int fn); Vector *get_lines (); @@ -146,7 +150,9 @@ private: void DoSpecialOpcode (int opcode); void EmitLine (); void reset (); + Vector *read_file_names_dwarf5 (); + Dwarf *dwarf; char *fname; uint64_t dir_index; uint64_t timestamp; @@ -167,7 +173,7 @@ private: bool basic_block; bool end_sequence; Vector *lines; - Vector *include_directories; + Vector *dir_names; Dwarf_Small *standard_opcode_length; DwrSec *debug_lineSec; uint64_t header_length; @@ -269,6 +275,7 @@ public: static char *at2str (int tag); static char *form2str (int tag); static char *tag2str (int tag); + static char *lnct2str (int ty); uint64_t cu_header_offset; uint64_t cu_offset; @@ -302,6 +309,7 @@ private: uint64_t stmt_list_offset; // offset in .debug_line section (DW_AT_stmt_list) char *comp_dir; // compilation directory (DW_AT_comp_dir) Module *module; + int unit_type; Dwarf_Half version; Dwarf_Small address_size; Dwr_Tag dwrTag; diff --git a/gprofng/src/collctrl.cc b/gprofng/src/collctrl.cc index 692d3e67528..5d68b689a64 100644 --- a/gprofng/src/collctrl.cc +++ b/gprofng/src/collctrl.cc @@ -114,7 +114,6 @@ Coll_Ctrl::Coll_Ctrl (int _interactive, bool _defHWC, bool _kernelHWC) #elif defined(__aarch64__) asm volatile("mrs %0, cntfrq_el0" : "=r" (cpu_clk_freq)); - dbe_write (2, GTXT ("CPU clock frequency: %d\n"), cpu_clk_freq); #else FILE *procf = fopen ("/proc/cpuinfo", "r"); @@ -1079,15 +1078,16 @@ Coll_Ctrl::set_synctrace (const char *string) /* the remaining string should be a number >= 0 */ char *endchar = NULL; int tval = (int) strtol (val, &endchar, 0); - free (val); if (*endchar != 0 || tval < 0) { + free (val); /* invalid setting */ /* restore the comma, if it was zeroed out */ if (comma_p != NULL) *comma_p = ','; return dbe_sprintf (GTXT ("Unrecognized synchronization tracing threshold `%s'\n"), string); } + free (val); synctrace_thresh = tval; synctrace_enabled = 1; return NULL; -- 2.31.1