* ldd.cc (longopts): Add --dll option.
(get_module_filename): Generalized wrapper function which avoid path length restrictions. (load_dll): Handle special-case of inspecting a DLL. (start_process): Accept an output parameter "isdll". Detect when file to start is a DLL and start a wrapper instead. (print_dlls_and_kill_inferior): When dealing with a DLL, avoid printing everything before the DLL itself first appears. (This is not strictly correct and should be fixed eventually) (report): Deal with DLLs. Don't set a breakpoint for DLLs, just let captive ldd process terminate normally. Pass dll info to print_dlls_and_kill_inferior. (main): Handle special-case "--dll" option by loading the DLL and exiting.
This commit is contained in:
parent
6612934a40
commit
d5e4f55b14
@ -1,3 +1,20 @@
|
|||||||
|
2009-03-14 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* ldd.cc (longopts): Add --dll option.
|
||||||
|
(get_module_filename): Generalized wrapper function which avoid path
|
||||||
|
length restrictions.
|
||||||
|
(load_dll): Handle special-case of inspecting a DLL.
|
||||||
|
(start_process): Accept an output parameter "isdll". Detect when file
|
||||||
|
to start is a DLL and start a wrapper instead.
|
||||||
|
(print_dlls_and_kill_inferior): When dealing with a DLL, avoid printing
|
||||||
|
everything before the DLL itself first appears. (This is not strictly
|
||||||
|
correct and should be fixed eventually)
|
||||||
|
(report): Deal with DLLs. Don't set a breakpoint for DLLs, just let
|
||||||
|
captive ldd process terminate normally. Pass dll info to
|
||||||
|
print_dlls_and_kill_inferior.
|
||||||
|
(main): Handle special-case "--dll" option by loading the DLL and
|
||||||
|
exiting.
|
||||||
|
|
||||||
2009-03-14 Corinna Vinschen <corinna@vinschen.de>
|
2009-03-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* path.cc (from_fstab): Use wcstombs/mbstowcs instead of
|
* path.cc (from_fstab): Use wcstombs/mbstowcs instead of
|
||||||
|
@ -50,6 +50,7 @@ struct option longopts[] =
|
|||||||
{"help", no_argument, NULL, 0},
|
{"help", no_argument, NULL, 0},
|
||||||
{"version", no_argument, NULL, 0},
|
{"version", no_argument, NULL, 0},
|
||||||
{"data-relocs", no_argument, NULL, 'd'},
|
{"data-relocs", no_argument, NULL, 'd'},
|
||||||
|
{"dll", no_argument, NULL, 'D'},
|
||||||
{"function-relocs", no_argument, NULL, 'r'},
|
{"function-relocs", no_argument, NULL, 'r'},
|
||||||
{"unused", no_argument, NULL, 'u'},
|
{"unused", no_argument, NULL, 'u'},
|
||||||
{0, no_argument, NULL, 0}
|
{0, no_argument, NULL, 0}
|
||||||
@ -83,19 +84,65 @@ usage (const char *fmt, ...)
|
|||||||
|
|
||||||
static HANDLE hProcess;
|
static HANDLE hProcess;
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_module_filename (HANDLE hp, HMODULE hm)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char *buf = NULL;
|
||||||
|
DWORD res;
|
||||||
|
for (len = 1024; (res = GetModuleFileNameEx (hp, hm, (buf = (char *) realloc (buf, len)), len)) == len; len += 1024)
|
||||||
|
continue;
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
free (buf);
|
||||||
|
buf = NULL;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
load_dll (const char *fn)
|
||||||
|
{
|
||||||
|
char *buf = get_module_filename (GetCurrentProcess (), NULL);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
printf ("ldd: GetModuleFileName returned an error %lu\n", GetLastError ());
|
||||||
|
exit (1); /* FIXME */
|
||||||
|
}
|
||||||
|
buf = (char *) realloc (buf, sizeof (" \"--dll\" \"\"") + strlen (buf));
|
||||||
|
strcat (buf, " --dll \"");
|
||||||
|
strcat (buf, fn);
|
||||||
|
strcat (buf, "\"");
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
start_process (const char *fn)
|
start_process (const char *fn, bool& isdll)
|
||||||
{
|
{
|
||||||
STARTUPINFO si = {};
|
STARTUPINFO si = {};
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
si.cb = sizeof (si);
|
si.cb = sizeof (si);
|
||||||
if (CreateProcess (NULL, (CHAR *) fn, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi))
|
CHAR *cmd;
|
||||||
|
if (strlen (fn) < 4 || strcasecmp (strchr (fn, '\0') - 4, ".dll") != 0)
|
||||||
{
|
{
|
||||||
|
cmd = strdup (fn);
|
||||||
|
isdll = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd = load_dll (fn);
|
||||||
|
isdll = true;
|
||||||
|
}
|
||||||
|
if (CreateProcess (NULL, cmd, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi))
|
||||||
|
{
|
||||||
|
free (cmd);
|
||||||
hProcess = pi.hProcess;
|
hProcess = pi.hProcess;
|
||||||
DebugSetProcessKillOnExit (true);
|
DebugSetProcessKillOnExit (true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free (cmd);
|
||||||
set_errno_and_return (1);
|
set_errno_and_return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,18 +194,31 @@ tocyg (char *win_fn)
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CYGWIN_DLL_LEN (strlen ("\\cygwin1.dll"))
|
||||||
static int
|
static int
|
||||||
print_dlls_and_kill_inferior (dlls *dll, const char *process_fn)
|
print_dlls_and_kill_inferior (dlls *dll, const char *dllfn, const char *process_fn)
|
||||||
{
|
{
|
||||||
|
bool printit = !dllfn;
|
||||||
while ((dll = dll->next))
|
while ((dll = dll->next))
|
||||||
{
|
{
|
||||||
char *fn;
|
char *fn;
|
||||||
char fnbuf[MAX_PATH + 1];
|
char *fullpath = get_module_filename (hProcess, (HMODULE) dll->lpBaseOfDll);
|
||||||
DWORD len = GetModuleFileNameEx (hProcess, (HMODULE) dll->lpBaseOfDll, fnbuf, sizeof(fnbuf) - 1);
|
if (!fullpath)
|
||||||
if (!len)
|
|
||||||
fn = strdup ("???");
|
fn = strdup ("???");
|
||||||
else
|
else
|
||||||
fn = tocyg (fnbuf);
|
{
|
||||||
|
if (printit)
|
||||||
|
fn = tocyg (fullpath);
|
||||||
|
else if (strcasecmp (fullpath, dllfn) != 0)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printit = true;
|
||||||
|
free (fullpath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
free (fullpath);
|
||||||
|
}
|
||||||
printf ("\t%s => %s (%p)\n", basename (fn), fn, dll->lpBaseOfDll);
|
printf ("\t%s => %s (%p)\n", basename (fn), fn, dll->lpBaseOfDll);
|
||||||
free (fn);
|
free (fn);
|
||||||
}
|
}
|
||||||
@ -181,11 +241,12 @@ report (const char *in_fn, bool multiple)
|
|||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
print_errno_error_and_return (fn);
|
print_errno_error_and_return (fn);
|
||||||
|
|
||||||
|
bool isdll;
|
||||||
char fn_win[len + 1];
|
char fn_win[len + 1];
|
||||||
if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, fn, fn_win, len))
|
if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, fn, fn_win, len))
|
||||||
print_errno_error_and_return (fn);
|
print_errno_error_and_return (fn);
|
||||||
|
|
||||||
if (!fn || start_process (fn_win))
|
if (!fn || start_process (fn_win, isdll))
|
||||||
print_errno_error_and_return (in_fn);
|
print_errno_error_and_return (in_fn);
|
||||||
|
|
||||||
DEBUG_EVENT ev;
|
DEBUG_EVENT ev;
|
||||||
@ -211,7 +272,7 @@ report (const char *in_fn, bool multiple)
|
|||||||
switch (ev.dwDebugEventCode)
|
switch (ev.dwDebugEventCode)
|
||||||
{
|
{
|
||||||
case LOAD_DLL_DEBUG_EVENT:
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
if (++dll_count == 2)
|
if (!isdll && ++dll_count == 2)
|
||||||
get_entry_point ();
|
get_entry_point ();
|
||||||
dll_last->next = (dlls *) malloc (sizeof (dlls));
|
dll_last->next = (dlls *) malloc (sizeof (dlls));
|
||||||
dll_last->next->lpBaseOfDll = ev.u.LoadDll.lpBaseOfDll;
|
dll_last->next->lpBaseOfDll = ev.u.LoadDll.lpBaseOfDll;
|
||||||
@ -219,10 +280,19 @@ report (const char *in_fn, bool multiple)
|
|||||||
dll_last = dll_last->next;
|
dll_last = dll_last->next;
|
||||||
break;
|
break;
|
||||||
case EXCEPTION_DEBUG_EVENT:
|
case EXCEPTION_DEBUG_EVENT:
|
||||||
if (ev.u.Exception.ExceptionRecord.ExceptionCode == STATUS_DLL_NOT_FOUND)
|
switch (ev.u.Exception.ExceptionRecord.ExceptionCode)
|
||||||
process_fn = fn_win;
|
{
|
||||||
else
|
case STATUS_DLL_NOT_FOUND:
|
||||||
print_dlls_and_kill_inferior (&dll_list, process_fn);
|
process_fn = fn_win;
|
||||||
|
break;
|
||||||
|
case STATUS_BREAKPOINT:
|
||||||
|
if (!isdll)
|
||||||
|
print_dlls_and_kill_inferior (&dll_list, isdll ? fn_win : NULL, process_fn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXIT_PROCESS_DEBUG_EVENT:
|
||||||
|
print_dlls_and_kill_inferior (&dll_list, isdll ? fn_win : NULL, process_fn);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -252,6 +322,10 @@ main (int argc, char **argv)
|
|||||||
case 'u':
|
case 'u':
|
||||||
usage ("option not implemented `-%c'", optch);
|
usage ("option not implemented `-%c'", optch);
|
||||||
exit (1);
|
exit (1);
|
||||||
|
case 'D':
|
||||||
|
if (!LoadLibrary (argv[optind]))
|
||||||
|
exit (1);
|
||||||
|
exit (0);
|
||||||
case 0:
|
case 0:
|
||||||
if (index == 1)
|
if (index == 1)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user