Skip Menu |

This queue is for tickets about the Proc-ProcessTable CPAN distribution.

Report information
The Basics
Id: 51470
Status: resolved
Priority: 0/
Queue: Proc-ProcessTable

People
Owner: Nobody in particular
Requestors: christian.boitel [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: invalid cmdline field returned under Linux when command lines are 20, 40, ... character long
Date: Thu, 12 Nov 2009 14:24:05 +0100
To: bug-Proc-ProcessTable [...] rt.cpan.org
From: Christian BOITEL <christian.boitel [...] gmail.com>
On one terminal, run a program that: prints its pid, defines its command line as a string of length being a modulo of 20 and waits a bit so you have time to run second program => Example: perl -e 'print "mypid=$$\n"; while (<>) { chomp(); $0 = $_; }' While the first program is working, do the following: 1/ display cmndline value of the test program using cat /proc/<mypid>/cmndline => this is to confirm it shows up with no garbagge at the end 2/ use a sample perl program using Proc::ProcessTable to display processes pid and cmndline attributes and grep the output to locate process created on first terminal => perl -e 'use Proc::ProcessTable; $t = new Proc::ProcessTable; foreach $p (@{$t->table}) {print "pid=".$p->{"pid"}.",cmdline=".$p->{"cmndline"}."\n"; }' | fgrep <mypid> => you should see additional characters at the end Example: Show quoted text
root> perl -e 'print "mypid=$$\n"; while (<>) { chomp(); $0 = $_; }'
mypid=2110 01234567890123456789 root.hpbl20050> {print "pid=".$p->{"pid"}.",cmdline=".$p->{"cmndline"}."\n"; }' | fgrep pid=2110 < pid=2110,cmdline=012345678901234567892110 28928 34820 211 (/proc) root.hpbl20050> cat /proc/2110/cmdline 01234567890123456789 Pb has been located in read_file function within os/Linux.c => bug therefore applies to all /proc/xxx/yyy files being read if it is a multiple of 20 in size => bug is just after the for loop that reads the file content into the obstack: from my understanding, it is useless to test after if len of data being read is a multiple of 20 the for loop will be executed at least once more than needed for loop exits if result is 0 (when eof is reached) (result must be 0 to exit) and therefore obstack is always 20 characters more long than needed --- Linux.c 2009-11-12 14:13:07.000000000 +0100 +++ Linux.c.original 2008-09-08 17:10:41.000000000 +0200 @@ -235,22 +235,26 @@ for (*len = 0; result; *len += result) { obstack_blank(mem_pool, 20); start = obstack_base(mem_pool) + *len; if ((result = read(fd, start, 20)) == -1) { obstack_free(mem_pool, obstack_finish(mem_pool)); return NULL; } } - start = obstack_base(mem_pool) + *len; - *start = '\0'; + /* null terminate */ + if (*len % 20) { + start = obstack_base(mem_pool) + *len; + *start = '\0'; + } else + obstack_1grow(mem_pool, '\0'); /* finalize our text buffer */ text = obstack_finish(mem_pool); /* not bothering checking return value, because it's possible that the * process went away */ close(fd); return text; }
Subject: Re: [rt.cpan.org #51470] AutoReply: invalid cmdline field returned under Linux when command lines are 20, 40, ... character long
Date: Thu, 12 Nov 2009 14:28:07 +0100
To: bug-Proc-ProcessTable [...] rt.cpan.org
From: Christian BOITEL <christian.boitel [...] gmail.com>
Sorry, mail was sent too early (before i completed it) so i was updated data below. 2009/11/12 Bugs in Proc-ProcessTable via RT < bug-Proc-ProcessTable@rt.cpan.org> Show quoted text
> > Greetings, > > This message has been automatically generated in response to the > creation of a trouble ticket regarding: > "invalid cmdline field returned under Linux when command lines are > 20, 40, ... character long", > a summary of which appears below. > > There is no need to reply to this message right now. Your ticket has been > assigned an ID of [rt.cpan.org #51470]. Your ticket is accessible > on the web at: > > http://rt.cpan.org/Ticket/Display.html?id=51470 > > Please include the string: > > [rt.cpan.org #51470] > > in the subject line of all future correspondence about this issue. To do > so, > you may reply to this message. > > Thank you, > bug-Proc-ProcessTable@rt.cpan.org > > ------------------------------------------------------------------------- > On one terminal, run a program that: prints its pid, defines its command > line as a string of length being a modulo of 20 and waits a bit so you have > time to run second program > => Example: perl -e 'print "mypid=$$\n"; while (<>) { chomp(); $0 = $_; }' > > While the first program is working, do the following: > 1/ display cmndline value of the test program using cat > /proc/<mypid>/cmndline > => this is to confirm it shows up with no garbagge at the end > 2/ use a sample perl program using Proc::ProcessTable to display processes > pid and cmndline attributes and grep the output to locate process created > on > first terminal > => > perl -e 'use Proc::ProcessTable; $t = new Proc::ProcessTable; foreach $p > (@{$t->table}) {print "pid=".$p->{"pid"}.",cmdline=".$p->{"cmndline"}."\n"; > }' | fgrep <mypid> > => you should see additional characters at the end > > Example: >
> root> perl -e 'print "mypid=$$\n"; while (<>) { chomp(); $0 = $_; }'
> mypid=2110 > 01234567890123456789 > > > root.hpbl20050> {print > "pid=".$p->{"pid"}.",cmdline=".$p->{"cmndline"}."\n"; > }' | fgrep pid=2110 < > pid=2110,cmdline=012345678901234567892110 28928 34820 211 > > (/proc) > root.hpbl20050> cat /proc/2110/cmdline > 01234567890123456789 > > > Pb has been located in read_file function within os/Linux.c > => bug therefore applies to all /proc/xxx/yyy files being read if it is a > multiple of 20 in size > => bug is just after the for loop that reads the file content into the > obstack: > from my understanding, it is useless to test after if len > of data being read is a multiple of 20 > the for loop will be executed at least once more than > needed for loop exits if result is 0 (when eof is reached) >
so it means the obstack is always at least 20 characters more long than needed Show quoted text
> so it is useless to extend the obstack if size read is a > multiple of 20 >
=> patch is below and has been tested successfully on my systems --- Linux.c.original 2008-09-08 17:10:41.000000000 +0200 +++ Linux.c 2009-11-12 14:13:07.000000000 +0100 @@ -235,26 +235,22 @@ for (*len = 0; result; *len += result) { obstack_blank(mem_pool, 20); start = obstack_base(mem_pool) + *len; if ((result = read(fd, start, 20)) == -1) { obstack_free(mem_pool, obstack_finish(mem_pool)); return NULL; } } - /* null terminate */ - if (*len % 20) { - start = obstack_base(mem_pool) + *len; - *start = '\0'; - } else - obstack_1grow(mem_pool, '\0'); + start = obstack_base(mem_pool) + *len; + *start = '\0'; /* finalize our text buffer */ text = obstack_finish(mem_pool); /* not bothering checking return value, because it's possible that the * process went away */ close(fd); return text; }
I'll take care asap - but currently I'm working on last changes for SQL::Statement 1.23. I hope after it I can start with Proc::ProcessTable. Thanks for your patch, Jens
Subject: [rt.cpan.org #51470]
Date: Fri, 13 Jul 2012 19:11:45 +0800
To: bug-Proc-ProcessTable [...] rt.cpan.org
From: Opera Wang <Opera.Wang [...] synopsys.com>
If change the read buffer from 20 to 1024, can fix the issue that sometimes Proc::ProcessTable report very big vsz/rss. Because /proc/$PID/stat file is larger than 20 bytes and if read multiple times, the file maybe get already changed and thus got corrupted data. Also this can improve performance, my own test shows that table() function call can reduce from 0.17s to 0.04s. Thanks.