From e2bf82d361423ee8cadbaf1a41f3a60d445967f5 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Fri, 24 Feb 2012 10:19:01 +0000 Subject: [PATCH] * Makefile.in (CYGWIN_BINS): Add pldd. (pldd.exe): Add -lpsapi to ALL_LDFLAGS. * pldd.c: New file. * utils.sgml (pldd): New section. --- winsup/utils/Makefile.in | 3 +- winsup/utils/pldd.c | 145 +++++++++++++++++++++++++++++++++++++++ winsup/utils/utils.sgml | 17 +++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 winsup/utils/pldd.c diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in index f85dd84ed..25ee5c48a 100644 --- a/winsup/utils/Makefile.in +++ b/winsup/utils/Makefile.in @@ -53,7 +53,7 @@ MINGW_CXX := ${srcdir}/mingw ${CXX} -I${updir} # List all binaries to be linked in Cygwin mode. Each binary on this list # must have a corresponding .o of the same name. CYGWIN_BINS := ${addsuffix .exe,cygpath getconf getfacl ldd locale kill mkgroup \ - mkpasswd mount passwd ps regtool setfacl setmetamode ssp tzset umount} + mkpasswd mount passwd pldd ps regtool setfacl setmetamode ssp tzset umount} # List all binaries to be linked in MinGW mode. Each binary on this list # must have a corresponding .o of the same name. @@ -81,6 +81,7 @@ ps.exe: ALL_LDFLAGS += -lcygwin -lpsapi -lntdll strace.exe: MINGW_LDFLAGS += -lntdll ldd.exe: ALL_LDFLAGS += -lpsapi +pldd.exe: ALL_LDFLAGS += -lpsapi ldh.exe: MINGW_LDLIBS := ldh.exe: MINGW_LDFLAGS := -nostdlib -lkernel32 diff --git a/winsup/utils/pldd.c b/winsup/utils/pldd.c new file mode 100644 index 000000000..c90a35033 --- /dev/null +++ b/winsup/utils/pldd.c @@ -0,0 +1,145 @@ +/* pldd.cc + + Copyright 2012 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#define WIN32_LEAN_AND_MEAN +#define UNICODE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct option longopts[] = +{ + {"help", no_argument, NULL, '?'}, + {"version", no_argument, NULL, 'V'}, + {"usage", no_argument, NULL, 0}, + {0, no_argument, NULL, 0} +}; +const char *opts = "?V"; + +__attribute__((noreturn)) +static void +print_help (void) +{ + printf ("Usage: pldd [OPTION...] PID\n\n" + "List dynamic shared objects loaded into a process.\n\n" + " -?, --help Give this help list\n" + " --usage Give a short usage message\n" + " -V, --version Print program version\n"); + exit (EXIT_SUCCESS); +} + +__attribute__((noreturn)) +static void +print_usage (void) +{ + printf ("Usage: pldd [-?V] [--help] [--usage] [--version] PID\n"); + exit (EXIT_SUCCESS); +} + +__attribute__((noreturn)) +static void +print_version () +{ + printf ("pldd (cygwin) %d.%d.%d\n" + "List dynamic shared objects loaded into process.\n" + "Copyright (C) 2012 Red Hat, Inc.\n\n" + "This program comes with NO WARRANTY, to the extent permitted by law.\n" + "You may redistribute copies of this program under the terms of\n" + "the Cygwin license. Please consult the CYGWIN_LICENSE file for details.\n", + CYGWIN_VERSION_DLL_MAJOR / 1000, + CYGWIN_VERSION_DLL_MAJOR % 1000, + CYGWIN_VERSION_DLL_MINOR); + exit (EXIT_SUCCESS); +} + +__attribute__((noreturn)) +static void +print_nargs (void) +{ + fprintf (stderr, "Exactly one parameter with process ID required.\n" + "Try `pldd --help' or `pldd --usage' for more information.\n"); + exit (EXIT_FAILURE); +} + +int +main (int argc, char *argv[]) +{ + int optch, pid, winpid, i; + char *pidfile, *exefile, *exename; + FILE *fd; + HANDLE hProcess; + HMODULE hModules[1024]; + DWORD cbModules; + + while ((optch = getopt_long (argc, argv, opts, longopts, &optind)) != -1) + switch (optch) + { + case '?': + print_help (); + break; + case 'V': + print_version (); + break; + case 0: + if (strcmp( "usage", longopts[optind].name ) == 0) + print_usage (); + break; + default: + break; + } + + argc -= optind; + argv += optind; + if (argc != 1) + print_nargs (); + + pid = atoi (argv[0]); + + if ((pid == 0)) + error (1, 0, "invalid process ID '%s'", argv[0]); + + pidfile = (char *) malloc (32); + sprintf(pidfile, "/proc/%d/winpid", pid); + fd = fopen (pidfile, "rb"); + if (!fd) + error (1, ENOENT, "cannot open /proc/%d", pid); + fscanf (fd, "%d", &winpid); + + exefile = (char *) malloc (32); + exename = (char *) malloc (MAX_PATH); + sprintf(exefile, "/proc/%d/exename", pid); + fd = fopen (exefile, "rb"); + fscanf (fd, "%s", exename); + + hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, winpid); + if (!hProcess) + error (1, EPERM, "cannot attach to process %d", pid); + + printf ("%d:\t%s\n", pid, exename); + + EnumProcessModules (hProcess, hModules, sizeof(hModules), &cbModules); + /* start at 1 to skip the executable itself */ + for (i = 1; i < (cbModules / sizeof(HMODULE)); i++) + { + TCHAR winname[MAX_PATH]; + char posixname[MAX_PATH]; + GetModuleFileNameEx (hProcess, hModules[i], winname, MAX_PATH); + cygwin_conv_path (CCP_WIN_W_TO_POSIX, winname, posixname, MAX_PATH); + printf ("%s\n", posixname); + } + + return 0; +} diff --git a/winsup/utils/utils.sgml b/winsup/utils/utils.sgml index fc7c1067d..b9bcc738c 100644 --- a/winsup/utils/utils.sgml +++ b/winsup/utils/utils.sgml @@ -1434,6 +1434,23 @@ some systems. +pldd + + +Usage: pldd [OPTION...] PID + +List dynamic shared objects loaded into a process. + + -?, --help Give this help list + --usage Give a short usage message + -V, --version Print program version + + +pldd prints the shared libraries (DLLs) loaded +by the process with the given PID. + + + ps