From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8551 invoked by alias); 17 Oct 2011 08:28:02 -0000 Received: (qmail 8279 invoked by uid 22791); 17 Oct 2011 08:27:36 -0000 X-Spam-Check-By: sourceware.org Received: from aquarius.hirmke.de (HELO calimero.vinschen.de) (217.91.18.234) by sourceware.org (qpsmtpd/0.83/v0.83-20-g38e4449) with ESMTP; Mon, 17 Oct 2011 08:27:21 +0000 Received: by calimero.vinschen.de (Postfix, from userid 500) id 6C0DC2CBDA0; Mon, 17 Oct 2011 10:27:18 +0200 (CEST) Date: Mon, 17 Oct 2011 08:28:00 -0000 From: Corinna Vinschen To: cygwin@cygwin.com Subject: Re: /proc/*/cmdline corrupted Message-ID: <20111017082718.GC30527@calimero.vinschen.de> Reply-To: cygwin@cygwin.com Mail-Followup-To: cygwin@cygwin.com References: <32663265.post@talk.nabble.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner@cygwin.com Mail-Followup-To: cygwin@cygwin.com X-SW-Source: 2011-10/txt/msg00307.txt.bz2 On Oct 16 16:59, Andrew DeFaria wrote: > On 10/16/11 14:31, jan.kolar wrote: > >>jc807j 2668 1 0 08:59 tty0 00:00:00 xterm -e ssh server > >80x72+285+0 -e ssh server > >>jc807j 3004 1 0 08:59 tty0 00:00:00 xterm -e ssh server > >>80x72-8+0 -e ssh server > >>jc807j 2928 5852 0 09:12 ? 00:00:00 xterm 20000 +tb > >>The actual command lines for the 3 xterm processes are: > >>C:\cygwin\bin\xterm.exe -sl 20000 +tb -geometry 80x72+285+0 -e ssh server > >>C:\cygwin\bin\xterm.exe -sl 20000 +tb -geometry 80x72-8+0 -e ssh server > >>C:\cygwin\bin\xterm.exe -sl 20000 +tb > >xterm calls XrmParseCommand() that > >"parses an (argc, argv) pair according to the specified option table ... and > >modifies the (argc, argv) pair to remove all recognized options." > > > >Therefore > > "-sl 20000 +tb -geometry 80x72+285+0" > >is properly removed > >and "-e ssh server" is moved to __argv[1 .. 3]. > >Then __argv[4] (respectively __argv[1] for the shorter command) is assigned > >null pointer > >which results in the second "\0" in the od-output below. > > > > > >HOWEVER: > > > >Either XrmParseCommand() does not update argc > >or the change does not propagate (how would that be possible?) to __argc. > >Therefore the command lines appear corrupted this particular way. > > > > > >/proc/*/cmdline uses a copy of __argc named __argc_safe > >which is hardly to be updated anyway. > >" for (int i = 0; i< __argc_safe; i++) " > > > >Funny enough, /proc/self/cmdline is likely to contain shortened version of > >cmdline: > >" for (char **a = __argv; *a; a++)" > >[ pinfo.cc from cygwin 1.7.9-1 ] > Why wouldn't exec(1) be responsible for setting up /proc and > therefore fill in cmdline with effectively $0 *before* the program > itself ever got around to calling XrmParseCommand? The content of /proc is generated on the fly at runtime, as soon as your application (like procps) opens the file in /proc. At exec time there's no storage for this information since we don't have a background service running all the time. To fetch the command line of a process, the opening process has to connect to the requested process via a bi-directional pipe and send a request for the command line. In the requested process, a thread constructs a copy of the __argv array and sends its contents back to the requesting process through the pipe. THat's the code Jan inspected. Thet code always scans through the entire __argv array from 0 to __argc - 1, irrespectively of some __argv[i] being NULL. If some __argv[i] is NULL or has an invalid pointer value, it is set to an empty string. This fully explains the output of the procps command. Since XrmParseCommand changes __argv, but not __argc, the output contains the full number of arguments, but in the, let's say, "crippled" state it's left when returning from XrmParseCommand. This can be easily changed, so that the /proc/$PID/cmdline output stops as soon as one of the arguments is NULL. That avoids the weird output, but it has a disadvantage. On Linux, /proc/$PID/cmdline always contains the full command line as it has been when the process got started, irrespectively of changes after process startup. It looks like the loader creates a copy of the argv array before calling main. Cygwin doesn't generate a copy of the argv array at startup, so the processes __argv is the one used to call the main function. And I'm reluctant to do that since it costs just more time for a process to start again. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple