From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by sourceware.org (Postfix) with ESMTPS id 8F8043840C1D for ; Sun, 14 Jun 2020 16:49:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8F8043840C1D Received: by mail-pl1-x632.google.com with SMTP id g12so5785558pll.10 for ; Sun, 14 Jun 2020 09:49:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=01K5cL3P8Ziue5Zxxi0db7k2sVrejbzEazc7SZu1nMo=; b=nXx56VvZkqxucYNWA1KKnzP4LEKaXLY+ZNy7o0CLZQdvbqfpRp+yG+WBYLpJcF5KZK hl5UYTzMm9Au9JX9LZj+Dz2de71mOV9H1/64nM6IOs8KW4TKjnUFJQ9cpxx57vwEostP 3Yyv4NIOKLlNy3qnETN8J5CIjRawrbeUtC8q9oiyhnFmCw7/Ebzeck4cyL3AAXLnI33W fPtIav2YIqFQQqZrsP1ugIE2xiPofY1mkyTTcFmY8m5LXYAWuGJZHu9CuEIx1KhOCCOd pR2S7ruQ3q9cJ+kPrdKu7Rl0MwJEskzyq6gRo63OSoddQ4SG677aFttDkNWDdV1ecmw2 iJGw== X-Gm-Message-State: AOAM5325qjIYgoCof01U356ynxpYE5bhzn5jmF+FhXDGJh+UxB71QmNy DauZeeSCkVuY+pQwHh0F6pPgCPZf1NPxTNqC8QOttgup X-Google-Smtp-Source: ABdhPJzu1RjF5a+no2+lAvvUxyemFmnO/VkeCmg6t6SB7K1p0ysE2Bbqm1d8NrvflsQXoQxCCnwpIQ3+TppAvGrDJq4= X-Received: by 2002:a17:90a:d244:: with SMTP id o4mr8034205pjw.186.1592153372555; Sun, 14 Jun 2020 09:49:32 -0700 (PDT) MIME-Version: 1.0 From: watashiwaher Date: Mon, 15 Jun 2020 01:49:21 +0900 Message-ID: Subject: [PATCH] Fixing get_builder() function in dwarf2/read.c To: gdb-patches@sourceware.org X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 14 Jun 2020 16:49:35 -0000 Explanation I found that some binaries with debug symbols halt gdb. And the problem was in the get_builder() function inside dwarf2/read.c file. The function recursively called itself until infinity. So I tried to fix this issue by eliminating recursion and adding the check for cycle detection, and returning nullptr if cycle detected. ChangeLog 2020-06-15 Slava Mitin * dwarf2/read.c (get_builder): Added check for cycles diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index e3073fe43c..e8c6d3bec3 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -594,15 +594,51 @@ struct dwarf2_cu /* Get the buildsym_compunit for this CU. */ buildsym_compunit *get_builder () { - /* If this CU has a builder associated with it, use that. */ - if (m_builder != nullptr) - return m_builder.get (); + /* Number of iterations before the updating of + the recursion_check_cu pointer */ + const int RECURSION_CHECK_UPDATE_INTERVAL = 2; - /* Otherwise, search ancestors for a valid builder. */ - if (ancestor != nullptr) - return ancestor->get_builder (); + /* Replacing recursion calls of get_builder + to the loop */ + dwarf2_cu *current_cu = this; - return nullptr; + /* Sometimes CUs can include each other recuresively, + so we need to stop iterating some day, if they do */ + dwarf2_cu *recursion_check_cu = nullptr; + + /* Counter of intervals */ + int recursion_check_counter = 1; + + while (true) { + /* If this CU has a builder associated with it, use that. */ + if (current_cu->m_builder != nullptr) { + return current_cu->m_builder.get(); + } + + /* Otherwise, search ancestors for a valid builder. */ + if (current_cu->ancestor != nullptr) { + current_cu = current_cu->ancestor; + } else { + return nullptr; + } + + /* If CU was seen already, return. */ + if (recursion_check_cu == current_cu) { + return nullptr; + } + + /* Update the variable used to check the recursion */ + if (recursion_check_counter == RECURSION_CHECK_UPDATE_INTERVAL) { + if (recursion_check_cu == nullptr) { + recursion_check_cu = this; + } else { + recursion_check_cu = recursion_check_cu->ancestor; + } + recursion_check_counter = 1; + } else { + recursion_check_counter++; + } + } } };