Bug 9363 - watch segmentation fault
: watch segmentation fault
Status: CLOSED WORKSFORME
: Sisyphus
(All bugs in Sisyphus/procps)
: unstable
: all Linux
: P2 normal
Assigned To:
:
:
:
:
:
  Show dependency tree
 
Reported: 2006-04-04 12:36 by
Modified: 2008-02-15 19:09 (History)


Attachments


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2006-04-04 12:36:04
Проблема с watch.c состоит в следующем. Смотрим watch.c
-------------------------------------------------
        command = strdup(argv[optind++]);
        command_length = strlen(command);
        for (; optind < argc; optind++) {
                int s = strlen(argv[optind]);
                char *endp = &command[command_length];
                *endp = ' ';
                command_length += s + 1;
                command = realloc(command, command_length + 1);
                strcpy(endp + 1, argv[optind]);
        }
-------------------------------------------------
man realloc говорит нам вот что
realloc() returns a pointer to the newly  allocated  memory,  which  is
suitably  aligned  for  any  kind of variable and may be different from
ptr
собственно, так оно и видно под отладчиком. realloc возвращает совершенно
другой
указатель, что в сочетании с установкой endp ДО realloc и записью в *endp ПОСЛЕ
realloc приводит к неожиданным эффектам.

у меня например это приводило к segmentation fault, если параметр у ls длиннее
8
символов. Т.е.
export LANG=ru_RU.CP1251 watch ls 12345678
работает, а
export LANG=ru_RU.CP1251 watch ls 123456789
уже нет

Ну собственно остается только сказать что в сизифном procsp этот кусок уже
переделан вот так:
-------------------------------------------------
                char *endp;
                int s = strlen(argv[optind]);
                command = realloc(command, command_length + s + 2);     /*
space
and \0 */
                endp = command + command_length;
                *endp = ' ';
                memcpy(endp + 1, argv[optind], s);
                command_length += 1 + s;        /* space then string length */
                command[command_length] = '\0';
-------------------------------------------------
------- Comment #1 From 2008-02-15 19:03:59 -------
moved to sisyphus
------- Comment #2 From 2008-02-15 19:09:31 -------
(In reply to comment #1)
> moved to sisyphus

Сизифный watch этой проблемы не имеет.