[pacman-dev] cvs unusable on x86_64

K. Piche kevin.piche at cgi.com
Thu Oct 26 17:33:19 EDT 2006


On Wed, 2006-10-25 at 10:56 -0500, Aaron Griffin wrote:
> On 10/25/06, Piche, Kevin <kevin.piche at cgi.com> wrote:
> > Frankly I don't like ftplib - it doesn't work with proxies so I have to
> > use wget.  Maybe we should switch to libcurl or something.
> 
> On this note, I agree 100% - but libcurl is messy.  I would prefer
> something along the lines of libarchive - maybe libfetch (also from
> bsd) ?
> 
> Are you sure this is an ftplib issue?
> 
> _______________________________________________
> pacman-dev mailing list
> pacman-dev at archlinux.org
> http://www.archlinux.org/mailman/listinfo/pacman-dev


While the SIG11 occurs within ftplib I think it's more of a compiler
issue actually after more investigation.  There's nothing obviously
wrong with the code however.  Here's my gdb trace:


[23:01 root at puffin pacman]$ gdb --args ./pacman.static -vSw vim
--noconfirm
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "x86_64-unknown-linux-gnu"...Using host
libthread_db
library "/lib/libthread_db.so.1".

(gdb) break FtpGet
Breakpoint 1 at 0x41e400: file ftplib.c, line 1248.
(gdb) run
Starting
program: /home/kpiche/pacman-devel/src/pacman-lib/src/pacman/pacman.static -vSw vim --noconfirm
Root  : /
DBPath: var/lib/pacman
Targets: vim
resolving dependencies... done.

Targets: vim-7.0.118-1

Total Package Size:   7.6 MB

Beginning download...

:: Retrieving packages from current...

Breakpoint 1, FtpGet (
    outputfile=0x7fff3c50e470
"/var/cache/pacman/pkg/vim-7.0.118-1.pkg.tar.gz.part", path=0x7742a0
"vim-7.0.118-1.pkg.tar.gz", mode=73 'I', nControl=0x777810)
    at ftplib.c:1248
1248    {
(gdb) s
1249            return FtpXfer(outputfile, path, nControl,
FTPLIB_FILE_READ, mode);
(gdb)
FtpXfer (
    localfile=0x7fff3c50e470
"/var/cache/pacman/pkg/vim-7.0.118-1.pkg.tar.gz.part", path=0x7742a0
"vim-7.0.118-1.pkg.tar.gz", nControl=0x777810, typ=3,
    mode=73) at ftplib.c:1101
1101    {
(gdb)
1108            if (localfile != NULL)
(gdb)
1101    {
(gdb)
1108            if (localfile != NULL)
(gdb)
1110                    char ac[4] = "a";
(gdb)
1112                            ac[0] = 'r';
(gdb)
1115                    local = fopen(localfile, ac);
(gdb)
1110                    char ac[4] = "a";
(gdb)
1112                            ac[0] = 'r';
(gdb)
1114                            ac[1] = 'b';
(gdb)
1112                            ac[0] = 'r';
(gdb)
1114                            ac[1] = 'b';
(gdb)
1115                    local = fopen(localfile, ac);
(gdb)
1116                    if (local == NULL)
(gdb)
1115                    local = fopen(localfile, ac);
(gdb)
1116                    if (local == NULL)
(gdb)
1125            if (!FtpAccess(path, typ, mode, nControl, &nData))
(gdb)
FtpAccess (path=0x7742a0 "vim-7.0.118-1.pkg.tar.gz", typ=3, mode=73,
    nControl=0x777810, nData=0x7fff3c50d3c8) at ftplib.c:802
802     {
(gdb)
805             if ((path == NULL) &&
(gdb) print nControl
$1 = (netbuf *) 0x777810
(gdb) print nControl->idlecb
$2 = (FtpCallback) 0x401e70 <log_progress>
(gdb) fin
Run till exit from #0  FtpAccess (path=0x7742a0
"vim-7.0.118-1.pkg.tar.gz",
    typ=3, mode=73, nControl=0x777810, nData=0x7fff3c50d3c8) at
ftplib.c:805
0x000000000041e298 in FtpXfer (
    localfile=0x7fff3c50e470
"/var/cache/pacman/pkg/vim-7.0.118-1.pkg.tar.gz.part", path=0x7742a0
"vim-7.0.118-1.pkg.tar.gz", nControl=0x777810, typ=3,
    mode=<value optimized out>) at ftplib.c:1125
1125            if (!FtpAccess(path, typ, mode, nControl, &nData))
Value returned is $3 = 1
(gdb) s
1127            dbuf = malloc(FTPLIB_BUFSIZ);
(gdb)
1128            if (typ == FTPLIB_FILE_WRITE)
(gdb)
1127            dbuf = malloc(FTPLIB_BUFSIZ);
(gdb)
1128            if (typ == FTPLIB_FILE_WRITE)
(gdb)
1140                    while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData))
> 0)
(gdb)
FtpRead (buf=0x779d60, max=8192, nData=0x779be0) at ftplib.c:872
872     {
(gdb)
874             if (nData->dir != FTPLIB_READ)
(gdb) print nData
$4 = (netbuf *) 0x779be0
(gdb) l
869      * FtpRead - read from a data connection
870      */
871     GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData)
872     {
873             int i;
874             if (nData->dir != FTPLIB_READ)
875                     return 0;
876             if (nData->buf)
877                     i = readline(buf, max, nData);
878             else
(gdb) print nData->dir
$5 = 1
(gdb)
$6 = 1
(gdb) s
872     {
(gdb)
874             if (nData->dir != FTPLIB_READ)
(gdb)
876             if (nData->buf)
(gdb) print nData->buf
$7 = 0x0
(gdb) s


So here FtpRead is about to call socket_wait.  Note the value of the
control structure pointer is 0x779be0.


880                     i = socket_wait(nData);
(gdb) print nData
$8 = (netbuf *) 0x779be0
(gdb) s
socket_wait (ctl=0x779be0) at ftplib.c:144
144     {
(gdb)
148             if ((ctl->dir == FTPLIB_CONTROL) || (ctl->idlecb ==
NULL))
(gdb) print ctl->idlecb
$9 = (FtpCallback) 0x401e70 <log_progress>
(gdb) s
150             if (ctl->dir == FTPLIB_WRITE)
(gdb)
154             FD_ZERO(&fd);
(gdb) print fd
$10 = {__fds_bits = {13, 7838112, 4100, 4518680, 140734205318097,
    140734205318097, 140734205318016, 4519571, 747324309664,
365072220369,
    566935683113, 8192, 8240, 140734205318096, 140734205322352,
7838112}}
(gdb) print *fd
Structure has no component named operator*.
(gdb) s
157                     FD_SET(ctl->handle,&fd);
(gdb) print fd
$11 = {__fds_bits = {0 <repeats 16 times>}}
(gdb) print ctl
$12 = (netbuf *) 0x779be0
(gdb) print ctl->handle
$13 = 14
(gdb) s
159                     rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);


...cut...  control ptr is still good.


socket_wait (ctl=0x779be0) at ftplib.c:144
144     {
(gdb)
148             if ((ctl->dir == FTPLIB_CONTROL) || (ctl->idlecb ==
NULL))
(gdb)
150             if (ctl->dir == FTPLIB_WRITE)
(gdb)
154             FD_ZERO(&fd);
(gdb)
157                     FD_SET(ctl->handle,&fd);
(gdb)
159                     rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);
(gdb)
157                     FD_SET(ctl->handle,&fd);
(gdb)
159                     rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);
(gdb)
157                     FD_SET(ctl->handle,&fd);
(gdb)
159                     rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);
(gdb)
157                     FD_SET(ctl->handle,&fd);
(gdb)
159                     rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);
(gdb)
158                     tv = ctl->idletime;
(gdb)
159                     rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);
(gdb)

160                     if (rv == -1)
(gdb)
167                     else if (rv > 0)
(gdb)
173             while ((rv = ctl->idlecb(ctl, ctl->xfered,
ctl->idlearg)));
(gdb)


Now we've called our callback function. ctl is still good.


log_progress (ctl=0x779be0, xfered=5792, arg=0x7fff3c51260c) at
download.c:56
56      {
(gdb) print ctl->handle
$31 = 14
(gdb) s
73              if(config->noprogressbar || (pct == 100 && lastpct ==
100)) {
(gdb)
57              int fsz = *(int*)arg;
(gdb) s
58              int pct = ((float)(xfered+offset) / fsz) * 100;
(gdb) print fsz
$32 = 7968150
(gdb)
$33 = 7968150
(gdb) s
73              if(config->noprogressbar || (pct == 100 && lastpct ==
100)) {
(gdb)
58              int pct = ((float)(xfered+offset) / fsz) * 100;
(gdb)
73              if(config->noprogressbar || (pct == 100 && lastpct ==
100)) {
(gdb)
77              alpm_get_option(PM_OPT_CHOMP, (long *)&chomp);
(gdb)
alpm_get_option (parm=29 '\035', data=0x7fff3c50d2bc) at alpm.c:153
153     {
(gdb)
155             ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
(gdb)
153     {
(gdb)
155             ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
(gdb)
156             ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
(gdb)
158             return(_alpm_handle_get_option(handle, parm, data));
(gdb)
159     }
(gdb)
alpm_get_option (parm=29 '\035', data=0x7fff3c50d2bc) at alpm.c:158
158             return(_alpm_handle_get_option(handle, parm, data));
(gdb)
_alpm_handle_get_option (handle=0x600560, val=29 '\035',
data=0x7fff3c50d2bc)
    at handle.c:315
315             ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
(gdb)
313     {
(gdb)
315             ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
(gdb)
317             switch(val) {
(gdb)
347                     case PM_OPT_CHOMP: *data = handle->chomp; break;
(gdb)
354     }
(gdb)
log_progress (ctl=<value optimized out>, xfered=5792,
    arg=<value optimized out>) at download.c:79
79              gettimeofday(&t1, NULL);
(gdb)
80              if(xfered+offset == fsz) {
(gdb)
83              timediff = t1.tv_sec-t.tv_sec +
(float)(t1.tv_usec-t.tv_usec) /
1000000;
(gdb)
94              } else if(timediff > 1) {
(gdb)
97                      rate = (xfered-xfered1) / (timediff * 1024);
(gdb)
99                      gettimeofday(&t, NULL);
(gdb)
97                      rate = (xfered-xfered1) / (timediff * 1024);
(gdb)
99                      gettimeofday(&t, NULL);
(gdb)
97                      rate = (xfered-xfered1) / (timediff * 1024);
(gdb)
99                      gettimeofday(&t, NULL);
(gdb)
98                      xfered1 = xfered;
(gdb)
97                      rate = (xfered-xfered1) / (timediff * 1024);
(gdb)
99                      gettimeofday(&t, NULL);
(gdb)
100                     eta_s = (fsz-(xfered+offset)) / (rate * 1024);
(gdb)
101                     eta_h = eta_s / 3600;
(gdb)
104                     eta_s -= eta_m * 60;
(gdb)
101                     eta_h = eta_s / 3600;
(gdb)
102                     eta_s -= eta_h * 3600;
(gdb)
103                     eta_m = eta_s / 60;
(gdb)
104                     eta_s -= eta_m * 60;
(gdb)
107             if(rate > 1000) {
(gdb)
110                     printf("%*s %6dK %6.1fK/s %02d:%02d:%02d [",
PM_DLFNM_LEN, sync_fnm, ((xfered+offset) / 1024), rate, eta_h, eta_m,
eta_s);
(gdb)
112             cur = (int)((maxcols-57)*pct/100);
(gdb)
113             for(i = 0; i < maxcols-57; i++) {
(gdb)
114                     if(chomp) {
(gdb)
138                             (i < cur) ? printf("#") : printf(" ");
(gdb)
113             for(i = 0; i < maxcols-57; i++) {


...cut...


113             for(i = 0; i < maxcols-57; i++) {
(gdb)
141             printf("] %3d%%\r", pct);
(gdb)
142             if(lastpct != 100 && pct == 100) {
(gdb)
147             fflush(stdout);
(gdb)
145             lastcur = cur;
(gdb)
146             lastpct = pct;
(gdb)
147             fflush(stdout);
(gdb)
vim-7.0.118-1               5K    0.0K/s 388:10:38
[                       ]   0149     }
(gdb)
socket_wait (ctl=0x0) at ftplib.c:157


We've printed our progress bar and return to socket_wait but now ctl is
NULL for some reason.  Then we die on the pointer dereference below.


157                     FD_SET(ctl->handle,&fd);
(gdb) print ctl
$41 = (netbuf *) 0x0
(gdb) print rv
$42 = 1
(gdb) s

Program received signal SIGSEGV, Segmentation fault.
socket_wait (ctl=0x0) at ftplib.c:157
157                     FD_SET(ctl->handle,&fd);
(gdb)
cleanup (signum=11) at pacman.c:183
183     {
(gdb) where
#0  cleanup (signum=11) at pacman.c:183
#1  <signal handler called>
#2  socket_wait (ctl=0x0) at ftplib.c:157
#3  0x000000000041c68b in FtpRead (buf=0x779d60, max=8192,
nData=0x5fb860)
    at ftplib.c:880
#4  0x000000000041e2e5 in FtpXfer (
    localfile=0x7fff3c50e470
"/var/cache/pacman/pkg/vim-7.0.118-1.pkg.tar.gz.part", path=<value
optimized out>, nControl=0x777810, typ=5792,
    mode=<value optimized out>) at ftplib.c:1140
#5  0x000000000041b3a3 in _alpm_downloadfiles_forreal (
    servers=<value optimized out>,
    localpath=0x7fff3c5156b0 "/var/cache/pacman/pkg", files=0x7742d0,
    mtime1=0x0, mtime2=0x0) at server.c:368
#6  0x000000000041bade in _alpm_downloadfiles (servers=0xffffffff,
    localpath=0x0, files=0x5fb860) at server.c:137
#7  0x00000000004190e3 in _alpm_sync_commit (trans=0x6068d0,
    db_local=0x606d90, data=0x7fff3c518ad8) at sync.c:820
#8  0x00000000004136cd in _alpm_trans_commit (trans=0x6068d0,
data=0x5fb860)
    at trans.c:217
#9  0x0000000000405ea7 in pacman_sync (targets=<value optimized out>)
    at sync.c:660
#10 0x0000000000407f4e in main (argc=<value optimized out>,
    argv=0x7fff3c519e38) at pacman.c:610
(gdb)


The wierd thing is that ctl is not modified by log_progress.  The only
explanation I can think of besides a compiler optimization bug is that
log_progress accesses the fsz variable which is just before the ctl
variable in main.  Moving the variable may fix it or refactoring the
code in socket_wait to get different assembler output.

k




More information about the pacman-dev mailing list