This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PR/2386 [2/2]: MinGW attach to process without an exec file


Christopher Faylor wrote:

On Fri, 28 Dec 2007 22:34:08 +0000 , Pedro Alves wrote:
Not useful in this case, as the pid gdb holds is the native Windows pid.
Hence current usage of cygwin_internal (CW_GETPINFO, ...).

I do find this less intrusive but I don't understand the above comment. Did you actually try using /proc and found it wanting? Finding a cygwin exename should be as simple as just doing a readlink ("/proc/<pid>/exe"). I just tried this on a top-level process created by cygwin and on the pid returned by typing "sleep 300&" in bash. The sleep process does have two pids associated with it due to the oddities of the way that cygwin emulates exec but "ls -l /proc/<pid>/exe" showed "/bin/sleep.exe" in each case.


From infcmd.c:attach_command :


  /*
   * If no exec file is yet known, try to determine it from the
   * process itself.
   */
  exec_file = (char *) get_exec_file (0);
  if (!exec_file)
    {
      exec_file = target_pid_to_exec_file (PIDGET (inferior_ptid));
      if (exec_file)
	{

So, the pid that is passed is what's stored in inferior_ptid.
It happens, that the win32-nat.c implementation stuff *thread* ids
in ptid_t structs, so PIDGET (inferior_ptid) extracts the current
inferior thread id -- not very useful for target_pid_to_exec_file,
hence the following comment in the current version of
win32_pid_to_exec_file:

/* Try to find the process path using the Cygwin internal process list
   pid isn't a valid pid, unfortunately.  Use current_event.dwProcessId
   instead.  */

(That's the I-have-a-patch-to-clean-that-up part.  But even then,
 PIDGET(inferior_ptid) will be the winpid.  We have room for it in the
 ptid_t, though, in the form of a lwp.  Note, *that* patch will
be invasive :-) )

What's stored in current_event.dwProcessId is a Windows PID, not a Cygwin
pid.  In that case, /proc/<pid>/exe isn't helpful, unless we can query Cygwin
for the cygpid associated with this pid, or we look though all the /proc/<pid>s
looking at a matching `cat /proc/<cygpid>/winpid`.

>sleep 300&
[3] 3848
[2]   Exit 1                  sleep
>cat /proc/3848/winpid
1788

Is there a reverse of CW_CYGWIN_PID_TO_WINPID ?

Even if the user specifies a cygwin pid to gdb --pid <cygpid>, win32_attach
does this:

/* Attach to process PID, then initialize for debugging it.  */
static void
win32_attach (char *args, int from_tty)
{
  BOOL ok;
  DWORD pid;
  pid = strtoul (args, 0, 0);		/* Windows pid */

ok = DebugActiveProcess (pid);

  if (!ok)
    {
      /* Try fall back to Cygwin pid */
      pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);

      if (pid > 0)
	ok = DebugActiveProcess (pid);
  }

We're calling win32 debug functions, so we internally
always care for the Windows pid.

Please do note that I'm not writting that part of the patch.
That Cygwin specific code is already there.  That is not to say
that I won't change it if you tell me how to get the winpid from
a cygwin pid.

For the rest of the code, have you investigated
"NtQuerySystemInformation"?  I don't know if it contains everything
needed but, despite what the Microsoft site says, it seems to have had a
stable interface for years and I don't see how Microsoft could change
the functionality without breaking lots of stuff.  I think it would be
better to adopt to probably nonexistent future API changes than it is
to rely on a DLL which may not be there.  I've always had a problem with
the psapi.h stuff for just the reasons that you mentioned.


I'm not sure if psapi.dll is that problematic. It should be quite widespread by now. Googling around shows that IE7 comes with it, for instance. In fact, google shows a lot of people with some app that doesn't load, because they have several versions of psapi.dll on the system, and the wrong version is being loaded. Following the lead of a lot of apps, we could *require* it, and instruct the user to get it, if it isn't found.

For kickers, I took a quick peek at Wine's implementation of
psapi.dll, and it was looking directly at PEB structures and
similar stuff -- those probably are even less stable.

There's a new API in Vista that gives us what we want, but
I forgot it's name, and can't re-find it... argh...

In this particular case, I'm now inclined to just go for
psapi.dll and be done with it.  We could load it in
_initialize_win32_nat and warn if we're on NT, and it
wasn't found ...

We use NtQuerySystemInformation in cygwin to return the list of
processes.  See pinfo.cc.


Not fully useable, I did try it. The ProcessName field in the SYSTEM_PROCESSES structure doesn't have a path, only the filename ...

I also looked into NtQueryInformationFile with FileNameInformation,
but that returns a file path starting from the root of the drive, that is:

\cygwin\bin\cat.exe, instead of \Device\Partition\cygwin\bin\cat.exe.
I couldn't find a way to get the drive letter from that info.

So, what shall I do ?  I've already posted several patches with
different combinations, so please, let's decide what to use, then I'll
post a patch.

1 - ToolHelp32
   - available on 9x, returns full path
   - available on NT >= 2000, return filename only [1], not a full path.
     Leaves NT4 out.

2 - PSAPI
   - Available on NT only, as a seperate dll.  I believe that on
     2000, it comes with one of the service packs.  XP, I believe
     comes with it.  I can't find anywhere specifying for sure
     which versions of Windows are bundled with it.  For all NT
     versions, it can be downloaded from MSFT.

3 - NtQueryObject(ObjectNameInfo) on the file handle.
   - Available on NT only, returns full path on XPSP2 at least.
   - [2] Will only work on the current inferior.  That is, if the 	
     target_pid_to_exec_file is used for something, else
     in the future, it will not work.  But that is not a problem
     currently.

4 - NtQueryInformationFile with FileNameInformation on the file handle.
   - Available on NT only, returns semi-full path
     relative to the drive base, but
   - Same as [2] above.

5 - NtQuerySystemInformation
   - Available on NT only, only returns filename [1], not a full path.

6 - Other ?

[1] - Gdb tries to cope with it, by looking for a match in the
      debug info.  Not very perfect, but the best it can be done.

In any case, we can put a warning in infcmd.c:attach_command,
when the exec file isn't found, instructing the user to use the
"file" command.

Looking at the options, I'd either go for '3 + 2 + 1' as in the
original patch, or just to '2 + 1' as in the latest patch.  I'm
more inclined into just '2 + 1' like in:
  http://sourceware.org/ml/gdb-patches/2007-12/msg00456.html

Chris, could you please take a peek at that patch ?  I think
you may have missed it.

For the Windows 9x case, I'd prefer if there was just a straightforward
error which indicated that what was being attempted is not available on
non-NT versions of Windows.


But why? It's not like supporting it in this case is hard. It can be shoved in 30 lines of code, just getting at toolhelp, and iterating over all the processes ... Pretty self contained, doesn't impact anything else.

--
Pedro Alves


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]