Непонятное поведение программы

Модератор: Модераторы разделов

Ответить
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Непонятное поведение программы

Сообщение ZyX »

Пытался написать программу, завис на функции создания лога. Функция на коды ошибок, состоящие из 5 и более 16ричных цифр (т.е. более половины) выдает "Segmentation fault (core dumped)". Если в конце присутствует хотя бы один ноль, то получается еще хуже (2ой блок, строчка r[b]='\' раскоментирована, тоже самое если строчка раскоментирована и число состоит из 5 и более 16ричных цифр, но нулей в конце нет). Я, конечно, могу и без этого обойтись, но эффект уж очень интересный. Также очень интересно превращение qйqйqйqйqйqйqйqйq1. в XпїЅпїЅXпїЅпїЅйqйqйqйqйqйq1 (здесь вместо "CпїЅ" один шестиугольник с вопросительным знаком). и дублирование записей (причем в файле t-4-1.log они также дублируются). Прошу объяснить происходящее.

Код:

zyx@zyx-desktop:~/Projects/t-4-1$ gcc -o t-4-1-.2 ./t-4-1-.2.c ./t-4-1-.2.c:44: предупреждение: conflicting types for built-in function ‘log’ zyx@zyx-desktop:~/Projects/t-4-1$ ./t-4-1-.2 >err.log Segmentation fault (core dumped) zyx@zyx-desktop:~/Projects/t-4-1$ ./t-4-1-.2 A000000A @qйqйqйqйqйqйqйqйq1. @Ошибка A00:error. AB0000AB XпїЅпїЅXпїЅпїЅйqйqйqйqйqйq1. @Ошибка A00:error. @Ошибка AB0:error. A0B00A0B XпїЅпїЅXпїЅпїЅйqйqйqйqйqйq1. @Ошибка A00:error. @Ошибка AB0:error. @Ошибка A0B:error. A77BA77B XпїЅпїЅXпїЅпїЅйqйqйqйqйqйq1. @Ошибка A00:error. @Ошибка AB0:error. @Ошибка A0B:error. @Ошибка A77:error. ABCCBABA XпїЅпїЅXпїЅпїЅйqйqйqйqйqйq1. @Ошибка A00:error. @Ошибка AB0:error. @Ошибка A0B:error. @Ошибка A77:error. @Ошибка ABC:error. Segmentation fault (core dumped) zyx@zyx-desktop:~/Projects/t-4-1$ cat err.log zyx@zyx-desktop:~/Projects/t-4-1$ ./t-4-1-.2 &>err.log Segmentation fault (core dumped) zyx@zyx-desktop:~/Projects/t-4-1$ cat err.log

Код:

zyx@zyx-desktop:~/Projects/t-4-1$ ./t-4-1-.2 A @qйqйqйqйqйqйqйqйq1. @Ошибка A:error. AB XCпїЅпїЅXCпїЅпїЅйqйqйqйqйqйq1. @Ошибка A:error. @Ошибка AB:error. A0B XCпїЅпїЅXCпїЅпїЅйqйqйqйqйqйq1. @Ошибка A:error. @Ошибка AB:error. @Ошибка A0B:error. A77B XCпїЅпїЅXCпїЅпїЅйqйqйqйqйqйq1. @Ошибка A:error. @Ошибка AB:error. @Ошибка A0B:error. @Ошибка A77:error. A700 XCпїЅпїЅXCпїЅпїЅйqйqйqйqйqйq1. @Ошибка A:error. @Ошибка AB:error. @Ошибка A0B:error. @Ошибка A77:error. @Ошибка A70:error. *** glibc detected *** ./t-4-1-.2: double free or corruption (out): 0x0804a090 *** ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6[0xb7e46d65] /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7e4a800] /lib/tls/i686/cmov/libc.so.6(fclose+0x134)[0xb7e356f4] ./t-4-1-.2[0x8048810] ./t-4-1-.2[0x80488b4] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7df3050] ./t-4-1-.2[0x80484c1] ======= Memory map: ======== 08048000-08049000 r-xp 00000000 08:12 3469 /home/zyx/Projects/t-4-1/t-4-1-.2 08049000-0804a000 rw-p 00000000 08:12 3469 /home/zyx/Projects/t-4-1/t-4-1-.2 0804a000-0806b000 rw-p 0804a000 00:00 0 [heap] b7c00000-b7c21000 rw-p b7c00000 00:00 0 b7c21000-b7d00000 ---p b7c21000 00:00 0 b7ddc000-b7ddd000 rw-p b7ddc000 00:00 0 b7ddd000-b7f21000 r-xp 00000000 08:03 13864 /lib/tls/i686/cmov/libc-2.6.1.so b7f21000-b7f22000 r--p 00143000 08:03 13864 /lib/tls/i686/cmov/libc-2.6.1.so b7f22000-b7f24000 rw-p 00144000 08:03 13864 /lib/tls/i686/cmov/libc-2.6.1.so b7f24000-b7f27000 rw-p b7f24000 00:00 0 b7f38000-b7f42000 r-xp 00000000 08:03 277665 /lib/libgcc_s.so.1 b7f42000-b7f43000 rw-p 0000a000 08:03 277665 /lib/libgcc_s.so.1 b7f43000-b7f46000 rw-p b7f43000 00:00 0 b7f46000-b7f60000 r-xp 00000000 08:03 13481 /lib/ld-2.6.1.so b7f60000-b7f62000 rw-p 00019000 08:03 13481 /lib/ld-2.6.1.so bfe87000-bfe9c000 rw-p bfe87000 00:00 0 [stack] ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso] Aborted (core dumped)

Код: Выделить всё

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
char *uitoa(unsigned int i)
{
        if(!i) return 0;
        char *r=(char *)malloc(sizeof(int)*2), j=sizeof(int)*2-1, b=0;
        while(j>=0) (r[(((r[sizeof(int)*2-1-j--]=(((r[sizeof(int)*2-1-j]=(i&(15<<(j*4)))>>(j*4))<10)?(r[sizeof(int)*2-1-j]+'0'):('A'+(r[sizeof(int)*2-1-j]-10))))!='0')||(b))?(b++):(b)]=r[sizeof(int)*2-j-2]);
        //r[b]='\'; //нолик потерялся при отправке на форум, в исходнике он присутствует
        putchar('\n');
        puts(r);
        putchar('\n');
        return (r);
}
int log(const char *message, unsigned int err_code)
{
        char *mes;
        mes = (char *) malloc(128);
        FILE *logf;
        if(!(logf=fopen("t-4-1.log","a+")))
        {
                puts("Невозможно открыть t-4-1.log");
                return (1);
        }
        strncat(mes,"@",1);
        if(err_code)
        {
                strncat(mes,"Ошибка ",13);
                strncat(mes,uitoa(err_code),3);
                strncat(mes,":",1);
        }
        strncat(mes,message,strlen(message));
        strncat(mes,".\n",2);
        if(err_code) fputs(mes,stdout);
        fputs(mes,logf);
        fclose(logf);
        free(mes);
        return (0);
}
int main(int argc, char *argv[])
{
        log("qйqйqйqйqйqйqйqйq1",0);
        log("error",0xA);
        log("error",0xAB);
        log("error",0xA0B);
        log("error",0xA77B);
        log("error",0xABCCBA);
        return (0);
}
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: Непонятное поведение программы

Сообщение drBatty »

1) строку 25 strncat(mes,"@",1); замените на strcpy(mes, "@");
2) все остальные strncat замените на strcat.
После malloc состояние строки неопределено, поэтому прибавляя к неопределённой строке что-то вы получаете неопределённое поведение.
3) Присваивание в строке 8 рекомендую отправить на конкурс непонятного программирования - бронза обеспечена ;)

PS: И уберите пожалуйста malloc. Разве в строке 7 нельзя было написать int r[2], а в строке 18 char mes[128]; ? Если же пользоваться локальными переменными вам нельзя по религиозным соображениям, то хотя бы проверяйте, что вам возвращает malloc.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Непонятное поведение программы

Сообщение ZyX »

drBatty писал(а):
02.12.2007 09:43
1) строку 25 strncat(mes,"@",1); замените на strcpy(mes, "@");
2) все остальные strncat замените на strcat.
После malloc состояние строки неопределено, поэтому прибавляя к неопределённой строке что-то вы получаете неопределённое поведение.
3) Присваивание в строке 8 рекомендую отправить на конкурс непонятного программирования - бронза обеспечена ;)

PS: И уберите пожалуйста malloc. Разве в строке 7 нельзя было написать int r[2], а в строке 18 char mes[128]; ? Если же пользоваться локальными переменными вам нельзя по религиозным соображениям, то хотя бы проверяйте, что вам возвращает malloc.
Большое спасибо, замена на strcpy помогла. А то я уж думал, придется мне присваивание в строке 8 разбирать, что гораздо сложнее чем собрать его из разных кусочков. В принципе, оно для того и делалось, чтобы никто не понял.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: Непонятное поведение программы

Сообщение drBatty »

ZyX писал(а):
02.12.2007 19:42
А то я уж думал, придется мне присваивание в строке 8 разбирать, что гораздо сложнее чем собрать его из разных кусочков. В принципе, оно для того и делалось, чтобы никто не понял.

В вашем коде нет ничего сложного, разобраться в нём можно за 2 минуты,
каким-нибудь нормальным редактором вроде kate.
Вот во что это превращается:

Код: Выделить всё

        while(j>=0)
            (r
                [
                    (
                        (
                            (
                                r[sizeof(int)*2-1-j--]=
                                    (
                                        (
                                            (
                                                r[sizeof(int)*2-1-j]
                                                =
                                                (
                                                    i&(15<<(j*4))
                                                )
                                            >>(j*4)
                                            )<10
                                        )
                                        ?
                                            (r[sizeof(int)*2-1-j]+'0')
                                        :
                                            ('A'+(r[sizeof(int)*2-1-j]-10))
                                    )
                                )
                                !='0'
                        )
                        ||(b)
                    )
                    ?
                        (b++)
                    :
                        (b)
                ]    = r[sizeof(int)*2-j-2]
            );
        //r[b]='\'; //нолик потерялся при отправке на форум, в исходнике он присутствует

Такое можно с лёгкостью переписать в совсем простой код ;)
Для запутывания врагов попробуйте #define, к примеру

Код: Выделить всё

#define i while
//где-то совсем в другом месте:
i(x = y(t));//Враг надолго задумается в поисках функции i :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Ответить