Bug 9363 - watch segmentation fault
Summary: watch segmentation fault
Status: CLOSED WORKSFORME
Alias: None
Product: Sisyphus
Classification: Development
Component: procps (show other bugs)
Version: unstable
Hardware: all Linux
: P2 normal
Assignee: Mikhail Efremov
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-04-04 12:36 MSD by Dmitry Vodennikov
Modified: 2008-02-15 19:09 MSK (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Vodennikov 2006-04-04 12:36:04 MSD
Проблема с 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 Michael Shigorin 2008-02-15 19:03:59 MSK
moved to sisyphus
Comment 2 Dmitry V. Levin 2008-02-15 19:09:31 MSK
(In reply to comment #1)
> moved to sisyphus

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