diff --git a/winsup/cygwin/release/3.2.1 b/winsup/cygwin/release/3.2.1
index 99c65ce30..4f4db622a 100644
--- a/winsup/cygwin/release/3.2.1
+++ b/winsup/cygwin/release/3.2.1
@@ -1,6 +1,13 @@
What's new:
-----------
+- An IP-sampling profiler named 'profiler' has been added. It can be used
+ to profile any Cygwin program along with any DLLs loaded.
+
+- A new tool 'gmondump' has been added. It can dump the raw information
+ of any "gmon.out" file created by profiler, ssp, or use of the gcc/g++
+ option '-pg'. (Continue using gprof to get symbolic profile displays.)
+
What changed:
-------------
diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml
index 1d9b8488c..0b7b5d0ea 100644
--- a/winsup/doc/utils.xml
+++ b/winsup/doc/utils.xml
@@ -793,6 +793,56 @@ line separates the ACLs for each file.
+
+
+ gmondump
+ 1
+ Cygwin Utilities
+
+
+
+ gmondump
+ Display formatted contents of profile data files
+
+
+
+
+gmondump [OPTION]... FILENAME...
+
+
+
+
+ Options
+
+ -h, --help Display usage information and exit
+ -v, --verbose Display more file details (toggle: default false)
+ -V, --version Display version information and exit
+
+
+
+
+ Description
+ The gmondump utility displays the contents of
+ one or more profile data files. Such files usually have names starting
+ with "gmon.out" and are created by a profiling program such as
+ profiler or ssp. Compiling your
+ gcc/g++ programs with option -pg also works.
+ By default, summary information is shown. You can use the
+ option -v to get more detailed displays.
+ Note that gmondump just displays the raw data;
+ one would usually use gprof to display the data in
+ a useful form incorporating symbolic info such as function names and
+ source line numbers.
+ Here is an example of gmondump operation:
+
+$ gmondump gmon.out.21900.zstd.exe
+file gmon.out.21900.zstd.exe, gmon version 0x51879, sample rate 100
+ address range 0x0x100401000..0x0x1004cc668
+ numbuckets 208282, hitbuckets 1199, hitcount 12124, numrawarcs 0
+
+
+
+
kill
@@ -2127,6 +2177,75 @@ specifying an empty password.
+
+
+ profiler
+ 1
+ Cygwin Utilities
+
+
+
+ profiler
+ Sampling profiler of Cygwin programs with their DLLs
+
+
+
+
+profiler [OPTION]... PROGRAM [ARG]...
+profiler [OPTION]... -p PID
+
+
+
+
+ Options
+
+ -d, --debug Display debugging messages (toggle: default false)
+ -e, --events Display Windows DEBUG_EVENTS (toggle: default false)
+ -f, --fork-profile Profiles child processes (toggle: default false)
+ -h, --help Display usage information and exit
+ -o, --output=FILENAME Write output to file FILENAME rather than stdout
+ -p, --pid=N Attach to running program with Cygwin pid N
+ ... or with Windows pid -N
+ -s, --sample-rate=N Set IP sampling rate to N Hz (default 100)
+ -v, --verbose Display more status messages (toggle: default false)
+ -V, --version Display version information and exit
+ -w, --new-window Launch given command in a new window
+
+
+
+
+ Description
+ The profiler utility executes a given program, and
+ optionally the children of that program, collecting the location of the
+ CPU instruction pointer (IP) many times per second. This gives a profile
+ of the program's execution, showing where the most time is being spent.
+ This profiling technique is called "IP sampling".
+
+ A novel feature of profiler is that time spent in
+ DLLs loaded with or by your program is profiled too. You use
+ gprof to process and display the resulting profile
+ information. In this fashion you can determine whether your own code,
+ the Cygwin DLL, or another DLL has "hot spots" that might benefit from
+ tuning.
+
+ (See also ssp, another profiler that
+ operates in a different fashion: stepping by instruction. This can
+ provide a different view on your program's operation.)
+
+ Here is an example of profiler operation:
+
+$ profiler du -khs .
+22G .
+97 samples across 83 buckets written to gmon.out.5908.cygwin1.dll
+4 samples across 4 buckets written to gmon.out.5908.KernelBase.dll
+1 sample across 1 bucket written to gmon.out.5908.kernel32.dll
+7318 samples across 42 buckets written to gmon.out.5908.ntdll.dll
+5 samples across 4 buckets written to gmon.out.5908.du.exe
+
+
+
+
+
ps
@@ -2775,6 +2894,10 @@ Example: ssp 0x401000 0x403000 hello.exe
gprof will claim the values are seconds, they really
are instruction counts. More on that later.
+ (See also profiler, another profiler that
+ operates in a different fashion: IP sampling. This can provide a
+ different view on your program's operation.)
+
Because the SSP was originally designed to profile the Cygwin DLL,
it does not automatically select a block of code to report statistics on.
You must specify the range of memory addresses to keep track of manually,
diff --git a/winsup/utils/Makefile.am b/winsup/utils/Makefile.am
index 9a846e39d..135e6143c 100644
--- a/winsup/utils/Makefile.am
+++ b/winsup/utils/Makefile.am
@@ -21,6 +21,7 @@ bin_PROGRAMS = \
gencat \
getconf \
getfacl \
+ gmondump \
kill \
ldd \
locale \
@@ -31,6 +32,7 @@ bin_PROGRAMS = \
mount \
passwd \
pldd \
+ profiler \
regtool \
setfacl \
setmetamode \
@@ -54,6 +56,7 @@ ldd_SOURCES = ldd.cc
locale_SOURCES = locale.cc
minidumper_SOURCES = minidumper.cc
mount_SOURCES = mount.cc path.cc
+profiler_SOURCES = profiler.cc path.cc
cygps_SOURCES = ps.cc
regtool_SOURCES = regtool.cc
umount_SOURCES = umount.cc
@@ -79,6 +82,8 @@ ldd_LDADD = $(LDADD) -lpsapi -lntdll
mount_CXXFLAGS = -DFSTAB_ONLY $(AM_CXXFLAGS)
minidumper_LDADD = $(LDADD) -ldbghelp
pldd_LDADD = $(LDADD) -lpsapi
+profiler_CXXFLAGS = -I$(srcdir) -idirafter ${top_srcdir}/cygwin -idirafter ${top_srcdir}/cygwin/include $(AM_CXXFLAGS)
+profiler_LDADD = $(LDADD) -lntdll
cygps_LDADD = $(LDADD) -lpsapi -lntdll
if CROSS_BOOTSTRAP