From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 2VtGCgSEAGH5CAAAWB0awg (envelope-from ) for ; Tue, 27 Jul 2021 18:09:08 -0400 Received: by simark.ca (Postfix, from userid 112) id 10E3C1EDFB; Tue, 27 Jul 2021 18:09:08 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id BFF651E813 for ; Tue, 27 Jul 2021 18:09:06 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A8A623983C7F for ; Tue, 27 Jul 2021 22:09:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A8A623983C7F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627423745; bh=HBcLBAehbwXl3z5LEFQkbKK+DGfCd/fQbmIcrmSDN9o=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=LYXD/dvr01Xe8fR3MIBiVGgelY03yS19v1qTPTI59YfWPlben1uEO3aKrwgBEg3RN acCkqVkvB0iC7rhusEUz1FLN29gEX0tQYioXWgXW2rm9HgQihmFtrSq/6vsNFE6pYF UXJvEjQ/NzyCHJS0CZA4+n1i+i+aRoMw6EsxmfxI= Received: from mail-qv1-xf36.google.com (mail-qv1-xf36.google.com [IPv6:2607:f8b0:4864:20::f36]) by sourceware.org (Postfix) with ESMTPS id 97D923854816 for ; Tue, 27 Jul 2021 22:08:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 97D923854816 Received: by mail-qv1-xf36.google.com with SMTP id f91so509067qva.9 for ; Tue, 27 Jul 2021 15:08:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=HBcLBAehbwXl3z5LEFQkbKK+DGfCd/fQbmIcrmSDN9o=; b=Pfyvl3BaEEXDzVzOE/YcFsP1iFif5UAeRO8E8fKa8J3YNSRVza5tlHr1shvSg2xwIc CLa8eJ9h8qvcM2iO5s1NVl6r1WAUi9zt+lR81PBg8I6DFXIxBa7XrmZm8BwZ8V7MUilU 7jnmfKah3kMsHwGtqQwdYq8uQ5luWf5eN0MMWRg+0HQAbS6L7yImb8wz4nIAuXul+kNt w/VE/KTk7/f1x54gjde5hZYIlupoNIfj0T2QknWX8eVXdmuLOKmUwFmQdZRS1Q68qQMi aRCl/xrNNVzheLEOZ0RfsVCJGAjEaY9r9ss/ZrzxOjQ6q9AbowzPgAKLsQObfQmsR9gl d54Q== X-Gm-Message-State: AOAM530rOSpRTrSfsgKeNP5/gDN2aqp7J89q6Ndx7b5ZdyysRmJzciZP R6OFuqbqPIAJElSzYs9549D72DJwvXmEBgkg X-Google-Smtp-Source: ABdhPJxvcw36p4JgWZv7goPZgL/rDsdlRUXcRTcaAPW0+EGtnA2CP+akRRR+3A5mXDPI2qElPQ7lxQ== X-Received: by 2002:a0c:8525:: with SMTP id n34mr21967436qva.19.1627423722001; Tue, 27 Jul 2021 15:08:42 -0700 (PDT) Received: from nuc10 (ec2-35-183-244-153.ca-central-1.compute.amazonaws.com. [35.183.244.153]) by smtp.gmail.com with ESMTPSA id d20sm2352601qkg.34.2021.07.27.15.08.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Jul 2021 15:08:41 -0700 (PDT) Date: Tue, 27 Jul 2021 15:08:39 -0700 To: gdb-patches@sourceware.org Subject: [RFC PATCH] Add a new 'info proc time' subcommand of 'info proc'. Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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: , From: Rustam Kovhaev via Gdb-patches Reply-To: Rustam Kovhaev Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" Sometimes (unfortunately) I have to review windows user-space cores in windbg, and there is one feature that I really want to implement in gdb, but I don't know whether it is a good idea or not, and why it has not yet been implemented in gdb. In wdbg there is a .time command that gives me time when core was taken. I could not find the same functionality in gdb and in elf core. I know about kernel core_pattern and timestamp, and there are user-space daemons that write the timestamp, and sometimes if I am lucky I can get timestamp from modified/created file attributes and this solves the problem most of the time, but quite often I get only core.PID file + some app log and there is no way for me to figure out when exactly the core was taken. Current patch does not take into account lots of things like endianness, cpu archs other than x86, other code paths, etc, and there is also kernel side to modify and coordinate, but it does work in my lab, and I was pretty happy to learn a little bit about the project. This command displays a timestamp when core was taken. include/ * elf/common.h (NT_TIME): new define bfd/ * elf.c (elfcore_grok_note): create new pseudosection .note.linuxcore.time for NT_TIME note. gdb/ * defs.h (IP_TIME): new define. * infcmd.c (info_proc_cmd_time): add new function. * linux-tdep.c (linux_make_corefile_notes): save NT_TIME note. (_initialize_infcmd): register 'info proc time' command. binutils/ * readelf.c (get_note_type): handle NT_TIME note. Signed-off-by: Rustam Kovhaev --- bfd/elf.c | 4 ++++ binutils/readelf.c | 2 ++ gdb/defs.h | 3 +++ gdb/infcmd.c | 12 ++++++++++++ gdb/linux-tdep.c | 29 ++++++++++++++++++++++++++++- include/elf/common.h | 1 + 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/bfd/elf.c b/bfd/elf.c index de5abafabf0..2fd1b24ba3f 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -10678,6 +10678,10 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) case NT_MEMTAG: return elfcore_make_memtag_note_section (abfd, note, 0); + + case NT_TIME: + return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.time", + note); } } diff --git a/binutils/readelf.c b/binutils/readelf.c index 5682837ed7b..a6c4e020945 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -18738,6 +18738,8 @@ get_note_type (Filedata * filedata, unsigned e_type) if (filedata->file_header.e_type == ET_CORE) switch (e_type) { + case NT_TIME: + return _("NT_TIME (timestamp)"); case NT_AUXV: return _("NT_AUXV (auxiliary vector)"); case NT_PRSTATUS: diff --git a/gdb/defs.h b/gdb/defs.h index 6dea4099554..51f0d123586 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -398,6 +398,9 @@ enum info_proc_what /* * Display `info proc files'. */ IP_FILES, + /* * Display `info proc time'. */ + IP_TIME, + /* * Display all of the above. */ IP_ALL }; diff --git a/gdb/infcmd.c b/gdb/infcmd.c index c183b60e81a..154f284c2db 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2934,6 +2934,14 @@ info_proc_cmd_files (const char *args, int from_tty) info_proc_cmd_1 (args, IP_FILES, from_tty); } +/* Implement `info proc time'. */ + +static void +info_proc_cmd_time (const char *args, int from_tty) +{ + info_proc_cmd_1 (args, IP_TIME, from_tty); +} + /* Implement `info proc all'. */ static void @@ -3288,6 +3296,10 @@ List absolute filename for executable of the specified process."), List files opened by the specified process."), &info_proc_cmdlist); + add_cmd ("time", class_info, info_proc_cmd_time, _("\ +Print timestamp when core was taken."), + &info_proc_cmdlist); + add_cmd ("all", class_info, info_proc_cmd_all, _("\ List all available info about the specified process."), &info_proc_cmdlist); diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 637d3d36a0b..40d9e53c133 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1192,6 +1192,23 @@ linux_read_core_file_mappings (struct gdbarch *gdbarch, } } +/* Implement "info proc time" for a corefile. */ + +static void linux_core_info_proc_time () +{ + size_t note_size; + time_t timestamp; + asection *section = bfd_get_section_by_name (core_bfd, ".note.linuxcore.time"); + if (section == nullptr) + return; + + note_size = bfd_section_size (section); + if (sizeof(timestamp) < note_size) + return; + if (bfd_get_section_contents (core_bfd, section, ×tamp, 0, note_size)) + printf_filtered ("core was taken at %s", ctime (×tamp)); +} + /* Implement "info proc mappings" for a corefile. */ static void @@ -1244,6 +1261,7 @@ linux_core_info_proc (struct gdbarch *gdbarch, const char *args, { int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL); int mappings_f = (what == IP_MAPPINGS || what == IP_ALL); + int time_f = (what == IP_TIME); if (exe_f) { @@ -1259,7 +1277,10 @@ linux_core_info_proc (struct gdbarch *gdbarch, const char *args, if (mappings_f) linux_core_info_proc_mappings (gdbarch, args); - if (!exe_f && !mappings_f) + if (time_f) + linux_core_info_proc_time(); + + if (!exe_f && !mappings_f && !time_f) error (_("unable to handle request")); } @@ -1984,10 +2005,16 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) { struct elf_internal_linux_prpsinfo prpsinfo; gdb::unique_xmalloc_ptr note_data; + time_t now; if (! gdbarch_iterate_over_regset_sections_p (gdbarch)) return NULL; + now = time(NULL); + note_data.reset (elfcore_write_note (obfd, note_data.release (), + note_size, "CORE", NT_TIME, + &now, sizeof(now))); + if (linux_fill_prpsinfo (&prpsinfo)) { if (gdbarch_ptr_bit (gdbarch) == 64) diff --git a/include/elf/common.h b/include/elf/common.h index 0d381f0d27b..51a50d025a0 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -593,6 +593,7 @@ #define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ #define NT_TASKSTRUCT 4 /* Contains copy of task struct */ #define NT_AUXV 6 /* Contains copy of Elfxx_auxv_t */ +#define NT_TIME 9 /* Contains time when core was taken */ #define NT_PRXFPREG 0x46e62b7f /* Contains a user_xfpregs_struct; */ /* note name must be "LINUX". */ #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -- 2.30.2