* Bill Allombert <bill.allomb...@math.u-bordeaux1.fr> [20090329 23:34]:
> On Sun, Mar 29, 2009 at 11:00:33PM +0200, Michael Prokop wrote:
> > * Bill Allombert <bill.allomb...@math.u-bordeaux1.fr> [20090329 22:05]:

> > The sad thing is that if update-menus is running under strace
> > (meaning: either directly invoked via strace or when "strace -p
> > $PID" attaches early enough) it's working as supposed to. If I'm
> > catching the process from the chroot to late I just see tons of the
> > mentioned EBADF errors and update-menus keeps hanging.

> This suggest some kind of race-condition between update-menus and the kernel.

ACK

> Could you try
> gdb /usr/bin/update-menus
> to see if it also works ?
> If it fails, then you can try to do
> single-step in read_pkginfo() to see what happen.

It fails under gdb as well:

[...]
(gdb) break read_pkginfo()
Breakpoint 1 at 0x804fbfc: file update-menus.cc, line 439.
(gdb) run
Starting program: /root/update-menus

Breakpoint 1, read_pkginfo () at update-menus.cc:439
439       string inst_states="installed\\|triggers-awaited\\|triggers-pending";
(gdb) s
441                   + " /{s/^.*\\("+inst_states+"\\) *//; s/[, ][, ]*/\\n/g; 
p}\"";
(gdb) s
std::operator+<char, std::char_traits<char>, std::allocator<char> > (
    __lhs=0x806028c "dpkg-query --show --showformat=\"\\${status} \\${provides} 
\\${package}\\n\" | sed -n -e \"/", __r...@0xffa1b9cc)
    at /usr/include/c++/4.2/bits/basic_string.tcc:675
675                   const basic_string<_CharT, _Traits, _Alloc>& __rhs)
(gdb) s
258           { return strlen(__s); }
(gdb) s
682          __str.reserve(__len + __rhs.size());
(gdb) s
262             : _Alloc(__a), _M_p(__dat) { }
(gdb) s
258           { return strlen(__s); }
(gdb) s
682           __str.reserve(__len + __rhs.size());
(gdb) s
683          __str.append(__lhs, __len);
(gdb) s
684           __str.append(__rhs);
(gdb) s
685           return __str;
(gdb) s
read_pkginfo () at /usr/include/c++/4.2/bits/basic_string.h:2111
2111          basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
(gdb) s
827             return this->append(__s, traits_type::length(__s));
(gdb) s
441                   + " /{s/^.*\\("+inst_states+"\\) *//; s/[, ][, ]*/\\n/g; 
p}\"";
(gdb) s
std::operator+<char, std::char_traits<char>, std::allocator<char> > 
(__l...@0xffa1b9c0, __r...@0xffa1b9cc) at 
/usr/include/c++/4.2/bits/basic_string.h:2074
2074          basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
(gdb) s
2072                  const basic_string<_CharT, _Traits, _Alloc>& __rhs)
(gdb) s
2074          basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
(gdb) s
2075          __str.append(__rhs);
(gdb) s
2076          return __str;
(gdb) s
read_pkginfo () at /usr/include/c++/4.2/bits/basic_string.h:2111
2111          basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
(gdb) s
827             return this->append(__s, traits_type::length(__s));
(gdb) s
441                   + " /{s/^.*\\("+inst_states+"\\) *//; s/[, ][, ]*/\\n/g; 
p}\"";
(gdb) s
442       pkgs = "exec /bin/bash -o pipefail -c '" + pkgs + "'";
(gdb) s
std::operator+<char, std::char_traits<char>, std::allocator<char> > 
(__lhs=0x80602e4 "exec /bin/bash -o pipefail -c '", __r...@0xffa1b9c8)
    at /usr/include/c++/4.2/bits/basic_string.tcc:675
675                   const basic_string<_CharT, _Traits, _Alloc>& __rhs)
(gdb) s
258           { return strlen(__s); }
(gdb) s
682           __str.reserve(__len + __rhs.size());
(gdb) s
262             : _Alloc(__a), _M_p(__dat) { }
(gdb) s
258           { return strlen(__s); }
(gdb) s
682           __str.reserve(__len + __rhs.size());
(gdb) s
683           __str.append(__lhs, __len);
(gdb) s
684           __str.append(__rhs);
(gdb) s
685           return __str;
(gdb) s
read_pkginfo () at /usr/include/c++/4.2/bits/basic_string.h:2111
2111          basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
(gdb) s
827             return this->append(__s, traits_type::length(__s));
(gdb) s
491           { return this->assign(__str); }
(gdb) s
442       pkgs = "exec /bin/bash -o pipefail -c '" + pkgs + "'";
(gdb) s
443       FILE *status = popen(pkgs.c_str(), "r");
(gdb) s
445       if (!status)
(gdb) sadduser
libapt-pkg-libc6.7-6-4.6
apt
libapt-inst-libc6.7-6-1.1
apt-utils
aptitude
atftp
attr

     [ snip rest of the package list ]

vim-common
vim-runtime
libz1
zlib1g
zsh
443       FILE *status = popen(pkgs.c_str(), "r");
(gdb)
445       if (!status)
(gdb)
449                       configinfo::report_verbose);
(gdb)
configinfo::report (this=0x8066c00, messa...@0xffa1b9ac, 
v=configinfo::report_verbose) at update-menus.cc:310
310     void configinfo::report(const std::string &message, verbosity_type v)
(gdb)
312       if(v <= verbosity) {
(gdb)
326     }
(gdb)
read_pkginfo () at update-menus.cc:454
454         if (fgets(tmp, MAX_LINE, status) != NULL) {
(gdb)
451       while (!feof(status))
(gdb)
454         if (fgets(tmp, MAX_LINE, status) != NULL) {
(gdb)
451       while (!feof(status))
(gdb)
454         if (fgets(tmp, MAX_LINE, status) != NULL) {
(gdb)
451       while (!feof(status))
(gdb)
454         if (fgets(tmp, MAX_LINE, status) != NULL) {
(gdb)
451       while (!feof(status))
(gdb)
454         if (fgets(tmp, MAX_LINE, status) != NULL) {
(gdb)
451       while (!feof(status))
(gdb)
454         if (fgets(tmp, MAX_LINE, status) != NULL) {
(gdb)
451       while (!feof(status))
(gdb)
[...]

> The fact that update-menus -v output the list of package seems to imply
> that it does pipe([x, 1]) or pipe([x, 2]). Well, at least,
>  we can tell which one it is: try
> update-menus -v >menu.out 2>menu.err
> and see whether the package list is in menu.out or menu.err.

The package list is in menu.out.

> > What I get inside strace (note: then update-menus is working fine):

> > write(2, "update-menus[31341]: Dpkg is not"..., 65) = 65
> > SYS_331(0xff800758, 0x80000, 0xf7dbaff4, 0x90e2928, 0x1) = -1 ENOSYS 
> > (Function not implemented)
> > pipe([4, 5])                            = 0
> > clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
> > child_tidptr=0xf7c7c718) = 31342

> > I guess the SYS_331 is just a strace specific thing.

> Actually 'SYS_331' means the syscall number 331. However
> /usr/include/asm/unistd_64.h stops at 294, so maybe this is
> a false syscall added by strace so it can catch it.

A right, thanks.

regards,
-mika-

Attachment: signature.asc
Description: Digital signature

Reply via email to