From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 2FwHHm7DWWdHdwwAWB0awg (envelope-from ) for ; Wed, 11 Dec 2024 11:53:02 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=KNeFQmhW; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 7642B1E097; Wed, 11 Dec 2024 11:53:02 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable autolearn_force=no version=4.0.0 Received: from server2.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 ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 03B501E091 for ; Wed, 11 Dec 2024 11:53:01 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 94CB43858D38 for ; Wed, 11 Dec 2024 16:53:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 94CB43858D38 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=KNeFQmhW Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id DA9033858D28 for ; Wed, 11 Dec 2024 16:51:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DA9033858D28 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 DA9033858D28 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=1733935911; cv=none; b=IUr8mqxMG2tl8qEmEc1uRgiyAEEcAnggjlt9Zq3Uwls7TMDyWhMucGb4gPhKCKDxToRShYIY4S5gABjYBGB7qU1q/2KYPqvXiY34nCZp9smPwYO08oaKmV9yDWDQ4PWKqyY0oWW7GAWhDSP6lXbddrqDbZTISC5cA09FWXk/mQw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1733935911; c=relaxed/simple; bh=vD9fp9L2WxQTgzhhhEc0+Rtdg1n+e5Ycik1VL3KRg+Q=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=i2mqQukgAJ82hipXdvWi3Jq3v0G74/BeOGSbGvgDU7a3Hzm+LVN468tWmPUBEVtjXYvlPSFKvKFSkgz1Z7y3lZ13+3EsnkHQSeODY93PAAeZm/NctPKKvVxxjGerH9TpfKTRsykSDhkoeeWMY9eaPk73jLtM6q8FMKNSTOCw7Y8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DA9033858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733935911; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=FUySTs/XhBj8dOq2zwqtIbZKVqbTRKqTBsaXTGQc5Y4=; b=KNeFQmhWyaPDyVf7KKSe1rVTdi+/5pCiH32vD2LkCfIDaS3lOVb5s6BZ1oNFruVGd1xDar RMrwP1fGaFyp8YbbK2nP7Zba75wID9JegEgs+sFmEpApoKoynQO15nLVkb1SEeZtuErdSj 0ArephyTA4qDPGYRgs3ST7FHhiD0CcQ= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-210-HwCKHiq0M4-Qj_7TFqnCDg-1; Wed, 11 Dec 2024 11:51:50 -0500 X-MC-Unique: HwCKHiq0M4-Qj_7TFqnCDg-1 X-Mimecast-MFC-AGG-ID: HwCKHiq0M4-Qj_7TFqnCDg Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-38639b4f19cso2583073f8f.0 for ; Wed, 11 Dec 2024 08:51:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733935909; x=1734540709; h=mime-version:message-id:date:references:in-reply-to:subject:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FUySTs/XhBj8dOq2zwqtIbZKVqbTRKqTBsaXTGQc5Y4=; b=ZQ9tEFPTMdNJGZLrosJqmN602mlQ4mtytXP71XVUInYFJA8YZrvLcNtkrume+PjEE3 7wSDgnRbT8PUmITfEqJ//7JYY9S7lGKJTgrBPMa3wRK2wCrf5wnbiPATg3vOGlCETMcO 9hfGfMMrPka0ROS21euAYulz+CjU//jOUHSNfdlrQ7jI/NB0iVPGGFPcgoc+HpVLH4lf wFmtyCH5AsxXdck1KDSrDyMbFxtByTfKjlH1WLQc5y1aHH5E1VBno9sCNW/FeE5NS1oz VlGLtiSKtEw4sOnX5raxcYd+g977YoSplb9dHf/dJGnMme0KtSZZCIra08qqM+5aNskk MhhA== X-Forwarded-Encrypted: i=1; AJvYcCU4i0s42oE/q4XSCiet5diuTaCrcgDmwuNFLooBXSYZiH4buaPBlG8+Iv/TTsKiV/032mMZce/CJD9L7g==@sourceware.org X-Gm-Message-State: AOJu0Yyrqj1l0xaJDG3YiKnncOPCiaPDBRt6r3QFckialZbdloQktHoQ RqIwnPjL+uy/JApZ0LE5yqhkQAEmd5R2koNt6iGhCoyAJ+V/HK4Zx+fVM7NSYoq+GiaebLn5muk O4Vn0paLoOvS6hc4/ZcS7v//XgH8reX7lNnK5HeMj87F8mfqvhAwneMu6oBxduYfzgpY= X-Gm-Gg: ASbGncutc22OgeHGwQxy5kJFSS4nHZ+TG4inF65DaUvq8nfhKszXrNbum2O26/vfaUU +/i3qZ0/qVtrYc7C8itFNkQg0vixOq/wGZLDBGSvmfePnDdBgrc6GQTnc32qh+kRnhzdpNwwLzk c4WxQG1ppvqtQrWZE3mlNPQh+6TQnXR4xF75iUbiXQfWzmH+98VIS38rjQw5+GIN2mJF8piKA7B RKuj5T70skE6Q8P3ATFty1VpE3KMnsP22KIqnpS0Hm5Sr3z417VxgUxucu8qamWJg6cIIYkruar DIWRmg== X-Received: by 2002:a05:6000:1787:b0:386:31a9:31ea with SMTP id ffacd0b85a97d-3864cea3c64mr3863313f8f.33.1733935908606; Wed, 11 Dec 2024 08:51:48 -0800 (PST) X-Google-Smtp-Source: AGHT+IENIF7QbnafvLbBx/WNt748ffiLFPC/fD/zN+Bw5ofthSm2zQ3MB/jga29ZozcyuFJHq81ICg== X-Received: by 2002:a05:6000:1787:b0:386:31a9:31ea with SMTP id ffacd0b85a97d-3864cea3c64mr3863287f8f.33.1733935908050; Wed, 11 Dec 2024 08:51:48 -0800 (PST) Received: from localhost (197.209.200.146.dyn.plus.net. [146.200.209.197]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434faba810csm100763415e9.18.2024.12.11.08.51.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 08:51:47 -0800 (PST) From: Andrew Burgess To: Keith Seitz , gdb-patches@sourceware.org Subject: Re: [PATCH] Add gstack script In-Reply-To: References: Date: Wed, 11 Dec 2024 16:51:45 +0000 Message-ID: <87v7vqgo2m.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: _t4OfeLSiD0u_oGBVaa_6HGE_QaDk1t4hgD6GfwMikI_1733935909 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Keith Seitz writes: > This commit adds support for a `gstack' command which Fedora has > been carrying for many years. gstack is a natural counterpart to > the gcore command. Whereas gcore dumps a core file, gstack prints > stack traces of a running process. > > There are many improvements over Fedora's version of this script. > The dependency on procfs is gone; gstack will run anywhere gdb > runs. The only runtime dependencies are bash and awk. > > The script includes suggestions from gdb/32325 to include > versioning and help. [If this approach to gdb/32325 is acceptable, > I could propagate the solution to gcore/gdb-add-index.] That would be amazing! > > I've rewritten the documentation, integrating it into the User Manual. > The manpage is now output using this one source. > > Example run (on x86_64 Fedora 40) > > $ gstack --help > Usage: gstack [-h|--help] [-v|--version] PID > Print a stack trace of a running program > > -h, --help Print this message then exit. > -v, --version Print version information then exit. > $ gstack -v > GNU gstack (GDB) 16.0.50.20241119-git > $ gstack 12345678 > Process 12345678 not found. > $ gstack $(pidof emacs) > Thread 6 (Thread 0x7f382a8006c0 (LWP 1265626) "pool-spawner"): > #0 0x00007f383ffca3dd in syscall () at /lib64/libc.so.6 > #1 0x00007f3849cc0ccd in g_cond_wait () at /lib64/libglib-2.0.so.0 > #2 0x00007f3849c2c61b in g_async_queue_pop_intern_unlocked () at /lib64/libglib-2.0.so.0 > #3 0x00007f3849c93a03 in g_thread_pool_spawn_thread () at /lib64/libglib-2.0.so.0 > #4 0x00007f3849c92813 in g_thread_proxy () at /lib64/libglib-2.0.so.0 > #5 0x00007f383ff486d7 in start_thread () at /lib64/libc.so.6 > #6 0x00007f383ffcc60c in clone3 () at /lib64/libc.so.6 > > Thread 5 (Thread 0x7f3829e006c0 (LWP 1265627) "gmain"): > #0 0x00007f383ffbe87d in poll () at /lib64/libc.so.6 > #1 0x00007f3849cc3c34 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0 > #2 0x00007f3849c63383 in g_main_context_iteration () at /lib64/libglib-2.0.so.0 > #3 0x00007f3849c633e1 in glib_worker_main () at /lib64/libglib-2.0.so.0 > #4 0x00007f3849c92813 in g_thread_proxy () at /lib64/libglib-2.0.so.0 > #5 0x00007f383ff486d7 in start_thread () at /lib64/libc.so.6 > #6 0x00007f383ffcc60c in clone3 () at /lib64/libc.so.6 > > Thread 4 (Thread 0x7f38294006c0 (LWP 1265628) "gdbus"): > #0 0x00007f383ffbe87d in poll () at /lib64/libc.so.6 > #1 0x00007f3849cc3c34 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0 > #2 0x00007f3849c67f37 in g_main_loop_run () at /lib64/libglib-2.0.so.0 > #3 0x00007f3849ec7682 in gdbus_shared_thread_func.lto_priv () at /lib64/libgio-2.0.so.0 > #4 0x00007f3849c92813 in g_thread_proxy () at /lib64/libglib-2.0.so.0 > #5 0x00007f383ff486d7 in start_thread () at /lib64/libc.so.6 > #6 0x00007f383ffcc60c in clone3 () at /lib64/libc.so.6 > > Thread 3 (Thread 0x7f3828a006c0 (LWP 1265629) "emacs"): > #0 0x00007f383ffca3dd in syscall () at /lib64/libc.so.6 > #1 0x00007f3849cc0ccd in g_cond_wait () at /lib64/libglib-2.0.so.0 > #2 0x00007f3849c2c61b in g_async_queue_pop_intern_unlocked () at /lib64/libglib-2.0.so.0 > #3 0x00007f3849c2c67c in g_async_queue_pop () at /lib64/libglib-2.0.so.0 > #4 0x00007f3842c340d9 in fc_thread_func () at /lib64/libpangoft2-1.0.so.0 > #5 0x00007f3849c92813 in g_thread_proxy () at /lib64/libglib-2.0.so.0 > #6 0x00007f383ff486d7 in start_thread () at /lib64/libc.so.6 > #7 0x00007f383ffcc60c in clone3 () at /lib64/libc.so.6 > > Thread 2 (Thread 0x7f3823e006c0 (LWP 1265630) "dconf worker"): > #0 0x00007f383ffbe87d in poll () at /lib64/libc.so.6 > #1 0x00007f3849cc3c34 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0 > #2 0x00007f3849c63383 in g_main_context_iteration () at /lib64/libglib-2.0.so.0 > #3 0x00007f382a845705 in dconf_gdbus_worker_thread () at /usr/lib64/gio/modules/libdconfsettings.so > #4 0x00007f3849c92813 in g_thread_proxy () at /lib64/libglib-2.0.so.0 > #5 0x00007f383ff486d7 in start_thread () at /lib64/libc.so.6 > #6 0x00007f383ffcc60c in clone3 () at /lib64/libc.so.6 > > Thread 1 (Thread 0x7f383b642280 (LWP 1265621) "emacs"): > #0 0x00007f383ffc9197 in pselect () at /lib64/libc.so.6 > #1 0x00000000006b9e01 in really_call_select.lto_priv () > #2 0x00000000006e1979 in xg_select () > #3 0x00000000006899d1 in wait_reading_process_output () > #4 0x000000000057e91c in kbd_buffer_get_event () > #5 0x0000000000580bc6 in read_char () > #6 0x0000000000589c03 in read_key_sequence.lto_priv () > #7 0x0000000000576135 in command_loop_1.lto_priv () > #8 0x00000000006131ce in internal_condition_case () > #9 0x000000000057569e in command_loop_2 () > #10 0x0000000000613127 in internal_catch () > #11 0x0000000000575af3 in command_loop () > #12 0x0000000000575bef in recursive_edit_1 () > #13 0x0000000000575ddd in Frecursive_edit () > #14 0x00000000004795a9 in main () > > Since this is essentially a complete rewrite of the original > script and documentation, I've chosen to only keep a 2024 copyright date. > --- > gdb/Makefile.in | 38 ++++++++- > gdb/NEWS | 3 + > gdb/configure | 15 +++- > gdb/configure.ac | 7 ++ > gdb/doc/Makefile.in | 11 ++- > gdb/doc/gdb.texinfo | 48 ++++++++++++ > gdb/gstack-1.in | 126 ++++++++++++++++++++++++++++++ > gdb/testsuite/gdb.base/gstack.c | 32 ++++++++ > gdb/testsuite/gdb.base/gstack.exp | 78 ++++++++++++++++++ > 9 files changed, 353 insertions(+), 5 deletions(-) > create mode 100755 gdb/gstack-1.in > create mode 100644 gdb/testsuite/gdb.base/gstack.c > create mode 100644 gdb/testsuite/gdb.base/gstack.exp > > diff --git a/gdb/Makefile.in b/gdb/Makefile.in > index ecb323d8f02..2bf4cda315c 100644 > --- a/gdb/Makefile.in > +++ b/gdb/Makefile.in > @@ -590,6 +590,7 @@ CONFIG_CLEAN = @CONFIG_CLEAN@ > CONFIG_INSTALL = @CONFIG_INSTALL@ > CONFIG_UNINSTALL = @CONFIG_UNINSTALL@ > HAVE_NATIVE_GCORE_TARGET = @HAVE_NATIVE_GCORE_TARGET@ > +HAVE_GSTACK = @HAVE_GSTACK@ > > CONFIG_SRC_SUBDIR = arch cli dwarf2 mi compile tui unittests guile python \ > target nat > @@ -1951,7 +1952,7 @@ generated_files = \ > # Flags needed to compile Python code > PYTHON_CFLAGS = @PYTHON_CFLAGS@ > > -all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb gcore > +all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb gcore gstack > @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=$(SUBDIRS)" subdir_do > > # Rule for compiling .c files in the top-level gdb directory. > @@ -2110,6 +2111,19 @@ install-only: $(CONFIG_INSTALL) > $(INSTALL_SCRIPT) gcore \ > $(DESTDIR)$(bindir)/$$transformed_name; \ > fi > + if test "x${HAVE_GSTACK}" != x; \ > + then \ > + transformed_name=`t='$(program_transform_name)'; \ > + echo gstack | sed -e "$$t"` ; \ > + if test "x$$transformed_name" = x; then \ > + transformed_name=gstack ; \ > + else \ > + true ; \ > + fi ; \ > + $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) ; \ > + $(INSTALL_SCRIPT) gstack \ > + $(DESTDIR)$(bindir)/$$transformed_name; \ > + fi > transformed_name=`t='$(program_transform_name)'; \ > echo gdb-add-index | sed -e "$$t"` ; \ > if test "x$$transformed_name" = x; then \ > @@ -2154,6 +2168,17 @@ uninstall: force $(CONFIG_UNINSTALL) > fi ; \ > rm -f $(DESTDIR)$(bindir)/$$transformed_name; \ > fi > + if test "x$(HAVE_GSTACK)" != x; \ > + then \ > + transformed_name=`t='$(program_transform_name)'; \ > + echo gstack | sed -e "$$t"` ; \ > + if test "x$$transformed_name" = x; then \ > + transformed_name=gstack ; \ > + else \ > + true ; \ > + fi ; \ > + rm -f $(DESTDIR)$(bindir)/$$transformed_name; \ > + fi > transformed_name=`t='$(program_transform_name)'; \ > echo gdb-add-index | sed -e "$$t"` ; \ > if test "x$$transformed_name" = x; then \ > @@ -2265,7 +2290,7 @@ clean mostlyclean: $(CONFIG_CLEAN) > # functionality described is if the distributed files are unmodified. > distclean: clean > @$(MAKE) $(FLAGS_TO_PASS) DO=distclean "DODIRS=$(CLEANDIRS)" subdir_do > - rm -f nm.h config.status config.h stamp-h b jit-reader.h gcore stamp-nmh > + rm -f nm.h config.status config.h stamp-h b jit-reader.h gcore gstack gstack.in stamp-nmh > rm -f gdb-gdb.py gdb-gdb.gdb > rm -f y.output yacc.acts yacc.tmp y.tab.h > rm -f config.log config.cache > @@ -2326,6 +2351,15 @@ jit-reader.h: $(srcdir)/jit-reader.in config.status > gcore: $(srcdir)/gcore.in config.status > $(ECHO_GEN) $(SHELL) config.status $(SILENT_FLAG) $@ > > +gstack: gstack.in version.c > + $(ECHO_GEN) \ > + vv=`grep 'version\[\] = ' version.c | grep -o '".*"' | tr -d \"`; \ > + sed -e "s,@VERSION@,$$vv," $< > $@ > + @chmod +x $@ > + > +gstack.in: $(srcdir)/gstack-1.in config.status > + $(ECHO_GEN) $(SHELL) config.status $(SILENT_FLAG) $@ > + > gdb-gdb.py: $(srcdir)/gdb-gdb.py.in config.status > $(ECHO_GEN) $(SHELL) config.status $(SILENT_FLAG) $@ > > diff --git a/gdb/NEWS b/gdb/NEWS > index 046daad0eae..4922a8aa38f 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -56,6 +56,9 @@ > > * The Ada 'Object_Size attribute is now supported. > > +* Newly installed $prefix/bin/gstack uses GDB to print stack traces of > + running processes. > + > * Python API > > ** Added gdb.record.clear. Clears the trace data of the current recording. > diff --git a/gdb/configure b/gdb/configure > index ec9bbd3a842..3f2e1450aa5 100755 > --- a/gdb/configure > +++ b/gdb/configure > @@ -760,6 +760,7 @@ HAVE_NATIVE_GCORE_TARGET > TARGET_OBS > AMD_DBGAPI_LIBS > AMD_DBGAPI_CFLAGS > +HAVE_GSTACK > ENABLE_BFD_64_BIT_FALSE > ENABLE_BFD_64_BIT_TRUE > subdirs > @@ -11499,7 +11500,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 11502 "configure" > +#line 11503 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -11605,7 +11606,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 11608 "configure" > +#line 11609 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -24974,6 +24975,12 @@ if test x${all_targets} = xtrue; then > fi > fi > > +HAVE_GSTACK=0 > +if test $gdb_native = yes; then > + HAVE_GSTACK=1 > +fi > + > + > # AMD debugger API support. > > > @@ -33694,6 +33701,8 @@ fi > > ac_config_files="$ac_config_files gcore" > > +ac_config_files="$ac_config_files gstack.in:gstack-1.in" > + > ac_config_files="$ac_config_files Makefile gdb-gdb.gdb gdb-gdb.py doc/Makefile data-directory/Makefile" > > > @@ -34794,6 +34803,7 @@ do > "jit-reader.h") CONFIG_FILES="$CONFIG_FILES jit-reader.h:jit-reader.in" ;; > "nm.h") CONFIG_LINKS="$CONFIG_LINKS nm.h:$GDB_NM_FILE" ;; > "gcore") CONFIG_FILES="$CONFIG_FILES gcore" ;; > + "gstack.in") CONFIG_FILES="$CONFIG_FILES gstack.in:gstack-1.in" ;; > "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; > "gdb-gdb.gdb") CONFIG_FILES="$CONFIG_FILES gdb-gdb.gdb" ;; > "gdb-gdb.py") CONFIG_FILES="$CONFIG_FILES gdb-gdb.py" ;; > @@ -36340,6 +36350,7 @@ _LT_EOF > done ;; > "nm.h":L) echo > stamp-nmh ;; > "gcore":F) chmod +x gcore ;; > + "gstack.in":F) chmod +x gstack.in ;; > > esac > done # for ac_tag > diff --git a/gdb/configure.ac b/gdb/configure.ac > index 21f5dc8dd30..49d420bfc41 100644 > --- a/gdb/configure.ac > +++ b/gdb/configure.ac > @@ -261,6 +261,12 @@ if test x${all_targets} = xtrue; then > fi > fi > > +HAVE_GSTACK=0 > +if test $gdb_native = yes; then > + HAVE_GSTACK=1 > +fi > +AC_SUBST(HAVE_GSTACK) > + > # AMD debugger API support. > > AC_ARG_WITH([amd-dbgapi], > @@ -2231,6 +2237,7 @@ GDB_AC_SELFTEST([ > GDB_AC_TRANSFORM([gdb], [GDB_TRANSFORM_NAME]) > GDB_AC_TRANSFORM([gcore], [GCORE_TRANSFORM_NAME]) > AC_CONFIG_FILES([gcore], [chmod +x gcore]) > +AC_CONFIG_FILES([gstack.in:gstack-1.in], [chmod +x gstack.in]) I wonder if the '[chmod +x gstack.in]' part could be dropped. When gstack.in is converted to gstack we +x the new gstack script, but gstack.in isn't really a script yet, right? > AC_CONFIG_FILES([Makefile gdb-gdb.gdb gdb-gdb.py doc/Makefile data-directory/Makefile]) > > AC_OUTPUT > diff --git a/gdb/doc/Makefile.in b/gdb/doc/Makefile.in > index 181325fd0c9..c75714b5de2 100644 > --- a/gdb/doc/Makefile.in > +++ b/gdb/doc/Makefile.in > @@ -188,7 +188,7 @@ TEXI2POD = perl $(srcdir)/../../etc/texi2pod.pl \ > POD2MAN = pod2man --center="GNU Development Tools" > > # List of man pages generated from gdb.texi > -MAN1S = gdb.1 gdbserver.1 gcore.1 gdb-add-index.1 > +MAN1S = gdb.1 gdbserver.1 gcore.1 gstack.1 gdb-add-index.1 > MAN5S = gdbinit.5 > MANS = $(MAN1S) $(MAN5S) > > @@ -199,6 +199,7 @@ POD_FILE_TMPS = $(patsubst %.1,%.pod,$(MAN1S)) \ > > HAVE_NATIVE_GCORE_TARGET = @HAVE_NATIVE_GCORE_TARGET@ > HAVE_NATIVE_GCORE_HOST = @HAVE_NATIVE_GCORE_HOST@ > +HAVE_GSTACK = @HAVE_GSTACK@ > > ### > > @@ -339,6 +340,10 @@ install-man1: $(MAN1S) > -a "$$p" = gcore.1; then \ > continue; \ > fi; \ > + if test "x$(HAVE_GSTACK)" = x \ > + -a "$$p" = gstack.1; then \ > + continue; \ > + fi; \ > if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ > f=`echo $$p | sed -e 's|^.*/||' -e '$(transform)'`; \ > echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(man1dir)/$$f'"; \ > @@ -363,6 +368,10 @@ uninstall-man1: > -a "$$i" = gcore.1; then \ > continue; \ > fi; \ > + if test "x$(HAVE_GSTACK)" = x \ > + -a "$$i" = gstack.1; then \ > + continue; \ > + fi; \ > echo "$$i"; \ > done | \ > sed -n '/\.1[a-z]*$$/p'; \ > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 99720f1206e..0156eff8633 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -50580,6 +50580,7 @@ Show the current verbosity setting. > * gdb man:: The GNU Debugger man page > * gdbserver man:: Remote Server for the GNU Debugger man page > * gcore man:: Generate a core file of a running program > +* gstack man:: Print a stack trace of a running program > * gdbinit man:: gdbinit scripts > * gdb-add-index man:: Add index files to speed up GDB > @end menu > @@ -51262,6 +51263,53 @@ Richard M. Stallman and Roland H. Pesch, July 1991. > @end ifset > @c man end > > +@node gstack man > +@heading gstack > + > +@c man title gstack Print a stack trace of a running program > + > +@format > +@c man begin SYNOPSIS gstack > +gstack [-h | --help] [-v | --version] @var{pid} > +@c man end > +@end format > + > +@c man begin DESCRIPTION gstack > +Print a stack trace of a running program with process ID @var{pid}. If the process > +is multi-threaded, @command{gstack} outputs backtraces for every thread which exists > +in the process. > +@c man end > + > +@c man begin OPTIONS gstack > +@table @env > +@item --help > +@itemx -h > +List all options, with brief explanations. > + > +@item --version > +@itemx -v > +Print version information and then exit. > +@end table > +@c man end > + > +@c man begin SEEALSO gstack > +@ifset man > +The full documentation for @value{GDBN} is maintained as a Texinfo manual. > +If the @code{info} and @code{gdb} programs and @value{GDBN}'s Texinfo > +documentation are properly installed at your site, the command > + > +@smallexample > +info gdb > +@end smallexample > + > +@noindent > +should give you access to the complete manual. > + > +@cite{Using GDB: A Guide to the GNU Source-Level Debugger}, > +Richard M. Stallman and Roland H. Pesch, July 1991. > +@end ifset > +@c man end > + > @node gdbinit man > @heading gdbinit > > diff --git a/gdb/gstack-1.in b/gdb/gstack-1.in > new file mode 100755 > index 00000000000..80e9b45e294 > --- /dev/null > +++ b/gdb/gstack-1.in > @@ -0,0 +1,126 @@ > +#!/usr/bin/env bash > + > +# 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 . > + > +# Print a stack trace of a running process. > +# Similar to the gcore command, but instead of creating a core file, > +# we simply have gdb print out the stack backtrace to the terminal. > + > +GDB=${GDB:-$(command -v gdb)} > +GDBARGS=${GDBARGS:-} > +PKGVERSION=@PKGVERSION@ > +VERSION=@VERSION@ > + > +function print_usage() { > + echo "Usage: $0 [-h|--help] [-v|--version] PID" 1>&2 > +} > + > +function print_try_help() { > + echo "Try '$0 --help' for more information." > +} > + > +function print_help() { > + print_usage > + echo "Print a stack trace of a running program" > + echo > + echo " -h, --help Print this message then exit." > + echo " -v, --version Print version information then exit." > +} > + > +function print_version() { > + echo "GNU gstack (${PKGVERSION}) ${VERSION}" > +} > + > +# Parse options. > +while getopts hv-: OPT; do > + if [ "$OPT" = "-" ]; then > + OPT="${OPTARG%%=*}" > + OPTARG="${OPTARG#'$OPT'}" > + OPTARG="${OPTARG#=}" > + fi > + > + case "$OPT" in > + h | help) > + print_help > + exit 0 > + ;; > + v | version) > + print_version > + exit 0 > + ;; > + \?) > + # getopts has already output an error message. > + print_try_help > + exit 2 ;; > + *) > + echo "$0: unrecognized option '--$OPT'" >&2 > + print_try_help > + exit 2 > + ;; > + esac > +done > +shift $((OPTIND-1)) > + > +# The sole remaining argument should be the PID of the process > +# whose backtrace is desired. > +if [ $# -ne 1 ]; then > + print_usage > + exit 1 > +fi > + > +PID=$1 > + > +awk_script=$(cat << EOF > +BEGIN { > + first=1 > + attach_okay=0 > +} > + > +/ATTACHED/ { > + attach_okay=1 > +} > + > +/^#/ { > + if (attach_okay) { > + print \$0 > + } > +} > + > +/^Thread/ { > + if (attach_okay) { > + if (!first) > + print "" > + first=0 > + print \$0 > + } > +} > +EOF > + ) > + > +# Run GDB and remove some unwanted noise. > +$GDB --quiet -nx $GDBARGS < +set width 0 > +set height 0 > +set pagination no > +set debuginfod enabled off > +define attach-bt > +attach \$arg0 > +echo "ATTACHED" > +thread apply all bt > +end > +attach-bt $PID > +EOF > +awk -- "$awk_script" > diff --git a/gdb/testsuite/gdb.base/gstack.c b/gdb/testsuite/gdb.base/gstack.c > new file mode 100644 > index 00000000000..a8716707560 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/gstack.c > @@ -0,0 +1,32 @@ > +/* 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 > +#include > + > +int > +main (void) > +{ > + const char msg[] = "looping\n"; > + > + /* Output a simple string for the expect script to monitor us. */ > + write (1, msg, strlen (msg)); > + > + for (;;) ; > + > + return 0; > +} > diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp > new file mode 100644 > index 00000000000..901a8fb7cef > --- /dev/null > +++ b/gdb/testsuite/gdb.base/gstack.exp > @@ -0,0 +1,78 @@ > +# 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 . > + > +require !gdb_protocol_is_remote > +standard_testfile > + > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}] == -1} { > + return -1 > +} > + > +set command "$binfile" > +set res [remote_spawn host $command] > +if { ![gdb_assert { ![expr {$res < 0 || $res == ""}] } "spawn inferior"] } { > + return > +} > + > +# The spawn id of the test inferior. > +set test_spawn_id $res > + > +# Wait for the spawned program to loop. > +set test "wait for inferior to loop" > +gdb_expect { > + -re "looping\r\n" { > + pass $test > + } > + eof { > + fail "$test (eof)" > + return > + } > + timeout { > + fail "$test (timeout)" > + return > + } > +} > + > +# The test case uses a very simple notification not to get caught by attach on > +# exiting the function. > + > +set test "spawn gstack" > +set pid [spawn_id_get_pid $test_spawn_id] > +set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $GDB_DATA_DIRECTORY\\ sh\\ ${srcdir}/../contrib/gstack.sh\\ $pid\\;echo\\ GSTACK-END" I haven't dug into what's going on in this test, but I notice that it references contrib/gstack.sh, which isn't in HEAD, and isn't in this patch. And when I run the test I see: PASS: gdb.base/gstack.exp: spawn gstack sh: /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/../contrib/gstack.sh: No such file or directory GSTACK-END PASS: gdb.base/gstack.exp: gstack exits with no error PASS: gdb.base/gstack.exp: gstack's exit status is 0 Which I guess indicates that (a) the file's missing, and (b) the test should be improved to catch this case? Thanks, Andrew > +set res [remote_spawn host $command] > +if { ![gdb_assert { ![expr {$res < 0 || $res == ""}] } $test] } { > + return > +} > + > +set test "got backtrace" > +gdb_test_multiple "" $test { > + -i "$res" -re "^#0 +(0x\[0-9a-f\]+ in )?\\.?func \\(\\) at \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in \\.?main \\(\\) at \[^\r\n\]*\r\nGSTACK-END\r\n\$" { > + pass $test > + exp_continue > + } > + > + eof { > + set result [wait -i $res] > + verbose $result > + > + gdb_assert { [lindex $result 2] == 0 } "gstack exits with no error" > + gdb_assert { [lindex $result 3] == 0 } "gstack's exit status is 0" > + > + remote_close host > + } > +} > + > +# Kill the test inferior. > +kill_wait_spawned_process $test_spawn_id > > base-commit: be740e7cc62fed098ad62cef3b2e2b25b44d8748 > -- > 2.47.0