From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 146423858C60 for ; Sat, 27 Jan 2024 21:37:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 146423858C60 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 146423858C60 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706391438; cv=none; b=Fex3aBJ7kJWckl1LSSOp28rWKkYdD+B353IWgtCCkHy+WwwFXkg58VH7BPK7a1LZAGXA+Jf7sz2dSH9I/ncfXseeAR5/pkho6w6+nkjwAow/Hi1vsTlgYYWbLseBtRypoVHhmsZhIPct942GO5mmH6bPZoVzOSKXmRQniCieZtI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706391438; c=relaxed/simple; bh=4AoIwLK6NmvbwEm17Tfnc9ZcCBg3xgkrjqOykYELcOQ=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=x9V7t8s4taA1ijoGCMs1Xh7W0oK1m3BgBYSk34dfRA3Yj+NblHe0b2z7Zzi3OhvO65HrZB94Ao0EN/gAGsHM0R2tdnfO7EyLdKOtl9UStnTRt0yH/hA1+ZmDdgPSirq+yuq+07N/SBjYaAKonqnZqgpTDvWcRy9GNCkDmqtZdNY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706391429; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=aIm6nw33SUpAKGqOYsUojVA9xNLqy26PeSnR6FcoUQc=; b=QcS30UvpdINqCaYNqMO9MfJIAMhc9K+spHwzz0OaoZxClqxwz2aXSzNTgW3GsDLIHd0FIQ qSXysBBau42RzJE4CAKKFcxEjcMBrB9/XfY5OcN8mubcZQboeMZX5x2tSvHdHKJetc4SJl y3jRAb437mtbyaW8RAoHRQ4edF4w2LM= Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-46-gsJQqZpZNfSUUX7B14dGDQ-1; Sat, 27 Jan 2024 16:37:06 -0500 X-MC-Unique: gsJQqZpZNfSUUX7B14dGDQ-1 Received: by mail-qt1-f200.google.com with SMTP id d75a77b69052e-42a87d0f6e4so19672961cf.2 for ; Sat, 27 Jan 2024 13:37:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706391425; x=1706996225; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=aIm6nw33SUpAKGqOYsUojVA9xNLqy26PeSnR6FcoUQc=; b=Fp5LRJD/QJTwHa5KFOTXD3kXTJ25BPaqTT1O4gIzwJE35hyF2/OML/dRBatz4AlLM2 Z7rNgxGDbyntt8aUT5zu70f1Q606vqmQhAooeQq6ya2TMMoFSJH+Wrlb2/KgEaqc64nc DG5vMzhzJM5scEsjOXxpAUUlS1NkXetkWmqEP9QEZr3ymCZzwdSCbsycV2fTQsF952Bp iExRqcz9ilURRMLdH2ar3O7zwTfn4bQNzew6M07C02rMtJSkD4R+S3aGPdiA7fPfdKpI NJMUEHS8cMznWkn6A/TifitvanL7Lxj+2Svcya8ZRE6W8LE+iNK8OFEgs+WSVk+RFvgE Sozw== X-Gm-Message-State: AOJu0YxfRdb5jNyq5Ktn8Ys4sZxO/zUlvVyvFvjbDMGlfVnroiDLRr+9 zMVgPtzxkGCoFodpC6DqB+vJQYGsGg3iAQaokCej3inwiGE1Bf5vQi43fpvleFgjL2xaNHpR3Rw Ym16pM+oYabr2vcldHx3W2hW4eDop0HeeD3AYe8jnqV7DhNPzoEn9Uw5UUloQm61PvSfvmjw2VJ jSCB7KGKjQ3UtoFQ2S6nYhuIrL5lwvfjX2MDi97Y2YcB0= X-Received: by 2002:a05:622a:1041:b0:42a:71c3:53c3 with SMTP id f1-20020a05622a104100b0042a71c353c3mr3315839qte.132.1706391425446; Sat, 27 Jan 2024 13:37:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IGYp3z/CURn0kVDvflKUpZ0ZIensb8QN4vnIUK/VsmPDKSwHFru7fJBAuu2rg4vrljje6C3Xw== X-Received: by 2002:a05:622a:1041:b0:42a:71c3:53c3 with SMTP id f1-20020a05622a104100b0042a71c353c3mr3315825qte.132.1706391424978; Sat, 27 Jan 2024 13:37:04 -0800 (PST) Received: from localhost (185.223.159.143.dyn.plus.net. [143.159.223.185]) by smtp.gmail.com with ESMTPSA id s40-20020a05622a1aa800b004281ce041f6sm1878757qtc.21.2024.01.27.13.37.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Jan 2024 13:37:04 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH] gdb: attach to a process when the executable has been deleted Date: Sat, 27 Jan 2024 21:37:01 +0000 Message-Id: X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,RCVD_IN_SORBS_WEB,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE 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: Bug PR gdb/28313 describes attaching to a process when the executable has been deleted. The bug is for S390 and describes how a user sees a message 'PC not saved'. On x86-64 (GNU/Linux) I don't see a 'PC not saved' message, but instead I see this: (gdb) attach 901877 Attaching to process 901877 No executable file now. warning: Could not load vsyscall page because no executable was specified 0x00007fa9d9c121e7 in ?? () (gdb) bt #0 0x00007fa9d9c121e7 in ?? () #1 0x00007fa9d9c1211e in ?? () #2 0x0000000000000007 in ?? () #3 0x000000002dc8b18d in ?? () #4 0x0000000000000000 in ?? () (gdb) Notice that the addresses in the backtrace don't seem right, quickly heading to 0x7 and finally ending at 0x0. What's going on, in both the s390 case and the x86-64 case is that the architecture's prologue scanner is going wrong and causing the stack unwinding to fail. The prologue scanner goes wrong because GDB has no unwind information. And GDB has no unwind information because, of course, the executable has been deleted. Notice in the example session above we get this line in the output: No executable file now. which indicates that GDB failed to find an executable to debug. For GNU/Linux when GDB tries to find an executable for a given pid we end up calling linux_proc_pid_to_exec_file in gdb/nat/linux-procfs.c. Within this function we call `readlink` on /proc/PID/exe to find the path of the actual executable. If the `readlink` call fails then we already fallback on using /proc/PID/exe as the path to the executable to debug. However, when the executable has been deleted the `readlink` call doesn't fail, but the path that is returned points to a non-existent file. I propose that we add an `access` call to linux_proc_pid_to_exec_file to check that the target file exists and can be read. If the target can't be read then we should fall back to /proc/PID/exe (assuming that /proc/PID/exe can be read). Now on x86-64 the output looks like this: (gdb) attach 901877 Attaching to process 901877 Reading symbols from /proc/901877/exe... Reading symbols from /lib64/libc.so.6... (No debugging symbols found in /lib64/libc.so.6) Reading symbols from /lib64/ld-linux-x86-64.so.2... (No debugging symbols found in /lib64/ld-linux-x86-64.so.2) 0x00007fa9d9c121e7 in nanosleep () from /lib64/libc.so.6 (gdb) bt #0 0x00007fa9d9c121e7 in nanosleep () from /lib64/libc.so.6 #1 0x00007fa9d9c1211e in sleep () from /lib64/libc.so.6 #2 0x000000000040117e in spin_forever () at attach-test.c:17 #3 0x0000000000401198 in main () at attach-test.c:24 (gdb) which is much better. I've also tagged the bug PR gdb/29782 which concerns the test gdb.server/connect-with-no-symbol-file.exp. After making this change, when running gdb.server/connect-with-no-symbol-file.exp GDB would now pick up the /proc/PID/exe file as the executable in some cases. As GDB is not restarted for the multiple iterations of this test GDB (or rather BFD) would given a warning/error like: (gdb) PASS: gdb.server/connect-with-no-symbol-file.exp: sysroot=target:: action=permission: setup: disconnect set sysroot target: BFD: reopening /proc/3283001/exe: No such file or directory (gdb) FAIL: gdb.server/connect-with-no-symbol-file.exp: sysroot=target:: action=permission: setup: adjust sysroot What's happening is that an executable found for an earlier iteration of the test is still registered for the inferior when we are setting up for a second iteration of the test. When the sysroot changes, if there's an executable registered GDB tries to reopen it, but in this case the file has disappeared (the previous inferior has exited by this point). I did think about maybe, when the executable is /proc/PID/exe, we should auto-delete the file from the inferior. But in the end I thought this was a bad idea. Not only would this require a lot of special code in GDB just to support this edge case: we'd need to track if the exe file name came from /proc and should be auto-deleted, or we'd need target specific code to check if a path should be auto-deleted..... ... in addition, we'd still want to warn the user when we auto-deleted the file from the inferior, otherwise they might be surprised to find their inferior suddenly has no executable attached, so we wouldn't actually reduce the number of warnings the user sees. So in the end I figured that the best solution is to just update the test to avoid the warning. This is easily done by manually removing the executable from the inferior once each iteration of the test has completed. Now, in bug PR gdb/29782 GDB is clearly managing to pick up an executable from the NFS cache somehow. I guess what's happening is that when the original file is deleted /proc/PID/exe is actually pointing to a file in the NFS cache which is only deleted at some later point, and so when GDB starts up we do manage to associate a file with the inferior, this results in the same message being emitted from BFD as I was seeing. The fix included in this commit should also fix that bug. One final note: On x86-64 GNU/Linux, the gdb.server/connect-with-no-symbol-file.exp test will produce 2 core files. This is due to a bug in gdbserver that is nothing to do with this test. These core files are created before and after this commit. I am working on a fix for the gdbserver issue, but will post that separately. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28313 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29782 --- gdb/nat/linux-procfs.c | 5 ++ gdb/testsuite/gdb.base/attach-deleted-exec.c | 29 ++++++++++ .../gdb.base/attach-deleted-exec.exp | 53 +++++++++++++++++++ .../connect-with-no-symbol-file.exp | 12 +++++ 4 files changed, 99 insertions(+) create mode 100644 gdb/testsuite/gdb.base/attach-deleted-exec.c create mode 100644 gdb/testsuite/gdb.base/attach-deleted-exec.exp diff --git a/gdb/nat/linux-procfs.c b/gdb/nat/linux-procfs.c index 6be3a26f252..b17e3120792 100644 --- a/gdb/nat/linux-procfs.c +++ b/gdb/nat/linux-procfs.c @@ -352,6 +352,11 @@ linux_proc_pid_to_exec_file (int pid) else buf[len] = '\0'; + /* Use /proc/PID/exe if the actual file can't be read, but /proc/PID/exe + can be. */ + if (access (buf, R_OK) != 0 && access (name, R_OK) == 0) + strcpy (buf, name); + return buf; } diff --git a/gdb/testsuite/gdb.base/attach-deleted-exec.c b/gdb/testsuite/gdb.base/attach-deleted-exec.c new file mode 100644 index 00000000000..ebfae87fbfb --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-deleted-exec.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +int +main () +{ + alarm (60); + + while (1) + usleep (100000); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/attach-deleted-exec.exp b/gdb/testsuite/gdb.base/attach-deleted-exec.exp new file mode 100644 index 00000000000..3e31c36bcc4 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-deleted-exec.exp @@ -0,0 +1,53 @@ +# Copyright (C) 2024 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Attach to a process, the executable for which has been deleted. On +# GNU/Linux GDB will spot the missing executable and fallback to use +# /proc/PID/exe instead. + +require can_spawn_for_attach +require {istarget *-linux*} + +standard_testfile + +if { [build_executable "failed to prepare" $testfile $srcfile] } { + return -1 +} + +set test_spawn_id [spawn_wait_for_attach $binfile] +set testpid [spawn_id_get_pid $test_spawn_id] + +# Move the executable rather than deleting it. This just to aid with +# debugging if someone needs to reproduce this test. +set binfile_moved ${binfile}_moved + +# Don't move BINFILE as the kernel will just assign a new name to the +# same inode; and the /proc/PID/exe link will continue to point to the +# renamed inode. +remote_exec host "cp $binfile $binfile_moved" +remote_exec host "rm $binfile" + +# Don't pass the executable when GDB starts. Instead rely on GDB +# finding the executable from the PID we attach too. +clean_restart + +# Attach. GDB should spot that the executable is gone and fallback to +# use /proc/PID/exe. +gdb_test "attach $testpid" \ + "Attaching to process $decimal\r\nReading symbols from /proc/${testpid}/exe\\.\\.\\..*" \ + "attach to process with deleted executable" + +# Cleanup. +kill_wait_spawned_process $test_spawn_id diff --git a/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp b/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp index 284004abadd..becd94d9f90 100644 --- a/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp +++ b/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp @@ -89,6 +89,18 @@ proc connect_no_symbol_file { sysroot action } { } } gdb_assert $ok "connection to GDBserver succeeded" + + # GDB will register /proc/PID/exe as the executable for some of + # these tests. Once the test has finished the inferior will still + # have /proc/PID/exe registered as its executable even though that + # file no longer exists (most likely). GDB will then complain + # about the inferior's executable having disappeared. Silence + # these warnings by removing any registered file from the + # executable. + gdb_test "with confirm off -- file" \ + [multi_line \ + "No executable file now\\." \ + "No symbol file now\\."] } # Make sure we have the original symbol file in a safe place to copy from. base-commit: 81b6f191f71fe0af5dd7b1c7c5b7737c3d249a66 -- 2.25.4