URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5470
[ Назад ]

Исходное сообщение
"Странности при записи в файл"

Отправлено zkrvova , 01-Июн-06 10:57 
Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но иногда в файл записывается какоето левое значение. Вот кусок кода:


            if (open_file(str, "r") == 0){
                fscanf(stream, "%f", &t_data[a].access_bonus);
            }else{
                t_data[a].access_bonus = 0;
            }
            fclose(stream);

    syslog(LOG_INFO,"Read access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);

            f_tmp = t_data[a].payment_traf;
            t_data[a].access_bonus += (f_tmp * t_data[a].price);

    syslog(LOG_INFO,"Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
    syslog(LOG_INFO,"Write payment_traf for user %s = %f",t_data[a].login, f_tmp);
    syslog(LOG_INFO,"Write price for user %s = %f",t_data[a].login, (f_tmp * t_data[a].price));

            if (open_file(str, "w") == 0){
    syslog(LOG_INFO,"1 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
                if (t_data[a].access_bonus >= 0){
    syslog(LOG_INFO,"2.1 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
                    fprintf(stream, "%.2f", t_data[a].access_bonus);
    syslog(LOG_INFO,"3.2 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
                }else{
    syslog(LOG_INFO,"2.2 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
                    fprintf(stream, "%.2f", 0);
    syslog(LOG_INFO,"3.2 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
                }
            }
            fclose(stream);
    syslog(LOG_INFO,"4 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);

        if (open_file(str, "r") == 0){
            fscanf(stream, "%f", &f_tmp);
        }else{
            f_tmp = 0;
        }
        fclose(stream);

    syslog(LOG_INFO,"Read after write access_bonus for user %s = %f",t_data[a].login, f_tmp);

А вот что происходит(из лога):
Read access_bonus for user zloydrug = 0.000000
Write access_bonus for user zloydrug = -0.300000
Write payment_traf for user zloydrug = -1.000000
Write price for user zloydrug = -0.300000
1 - Write access_bonus for user zloydrug = -0.300000
2.2 - Write access_bonus for user zloydrug = -0.300000
3.2 - Write access_bonus for user zloydrug = -0.300000
4 - Write access_bonus for user zloydrug = -0.300000
Read after write access_bonus for user zloydrug = 72.349998


Как видно расчёт происходит правильно, и в файл записуется 0. Но после записи уже читается число 72.
Почему? Я понять пока немогу.

Причём происходит это не всегда а изредка.

Что делать? подскажите!
Спасибо!


Содержание

Сообщения в этом обсуждении
"Странности при записи в файл"
Отправлено NuINu , 01-Июн-06 13:07 
>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>иногда в файл записывается какоето левое значение. Вот кусок кода:
>

>
>Что делать? подскажите!
>Спасибо!

Пожалуйста ;-)))
А в файле то у тебя что записалось????
Потому как то что ты читаешь из файла и то что там есть - это две большие разницы.

И уж как минимум надо(думаю) ставить строку формата чтения, точно такой же как и у формата записи.
А вообще у тебя как, на каждого пользователя по файлу что ли??? или ты еще как то хитро позиционируешь??? просто здесь не показал...


"Странности при записи в файл"
Отправлено zkrvova , 01-Июн-06 14:24 
>>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>
>
>>
>>Что делать? подскажите!
>>Спасибо!
>
>Пожалуйста ;-)))
>А в файле то у тебя что записалось????
>Потому как то что ты читаешь из файла и то что там
>есть - это две большие разницы.

То и записалось, то что выдаёт то там и есть т.е. 72 с копейками.
Но каждый раз разные значения бывают. РАньше было 20 с чемто, а теперь 72.

>И уж как минимум надо(думаю) ставить строку формата чтения, точно такой же
>как и у формата записи.

Так строка формата отличается только количеством цифр после запятой, недумаю что из за этого добавляются целые числа.

>А вообще у тебя как, на каждого пользователя по файлу что ли???
>или ты еще как то хитро позиционируешь??? просто здесь не показал...
>


на каждого юзера по каталогу и в коталоге файлы с данными. Юзеры обрабатываются по очереди, т.е. сначала все данные одного обработались, потом пошли другие.


"Странности при записи в файл"
Отправлено NuINu , 01-Июн-06 15:08 
>>>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>>>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>>
>>

>
>на каждого юзера по каталогу и в коталоге файлы с данными. Юзеры
ужас какой!!!!

>обрабатываются по очереди, т.е. сначала все данные одного обработались, потом пошли
>другие.


Слушай а у тебя приложение не многопоточное???

вообще мне не нравиться твое глобальное stream, ты вызываешь некую функцию open_file
а потом начинаешь записывать в некий stream, где гаранти что ее кто-нибудь в этот момент не вызовет, и не поменяет нафиг, а может откуда нибудь еще в этот стрим пишеться...

Кстати в этот файл может только это приложение писать???


"Странности при записи в файл"
Отправлено zkrvova , 01-Июн-06 15:38 
>>>>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>>>>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>>>
>>>
>
>>
>>на каждого юзера по каталогу и в коталоге файлы с данными. Юзеры
>ужас какой!!!!
>
>>обрабатываются по очереди, т.е. сначала все данные одного обработались, потом пошли
>>другие.
>
>
>Слушай а у тебя приложение не многопоточное???
>
>вообще мне не нравиться твое глобальное stream, ты вызываешь некую функцию open_file
>
>а потом начинаешь записывать в некий stream, где гаранти что ее кто-нибудь
>в этот момент не вызовет, и не поменяет нафиг, а может
>откуда нибудь еще в этот стрим пишеться...
>
>Кстати в этот файл может только это приложение писать???


В этот файл только эта прога может писать.
Другая из этого файла читает.

Данная прога вызывается 1 раз в минуту и она не многопоточная ,она просто в цикле переберает данные и всё.


"Странности при записи в файл"
Отправлено NuINu , 01-Июн-06 16:11 
так ты это, смотри что возвращает fprintf и пиши результат в лог..

"Странности при записи в файл"
Отправлено zkrvova , 01-Июн-06 16:26 
>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>


Хорошая идея, попробую.


"Странности при записи в файл"
Отправлено SnaiL , 02-Июн-06 13:29 
>>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>>
>
>
>Хорошая идея, попробую.

А отладчиком воспользоваться - не судьба?


"Странности при записи в файл"
Отправлено zkrvova , 02-Июн-06 15:58 
>>>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>>>
>>
>>
>>Хорошая идея, попробую.
>
>А отладчиком воспользоваться - не судьба?


Для тех кто в танке - читай с начала: "Такое происходит изредка"
В отладчике таких проблем небыло замечено чтолько после месяца работы.


"Странности при записи в файл"
Отправлено SnaiL , 02-Июн-06 16:01 
>>>>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>>>>
>>>
>>>
>>>Хорошая идея, попробую.
>>
>>А отладчиком воспользоваться - не судьба?
>
>
>Для тех кто в танке - читай с начала: "Такое происходит изредка"
>
>В отладчике таких проблем небыло замечено чтолько после месяца работы.

Не знаю, кто в танке, но под такие дела пишутся ТЕСТЫ. Чудес компьютеры не творят, поэтому ТЕСТЫ + отладчик (если нужно) решают ЛЮБЫЕ проблемы и разъясняют что, где не так, как хотелось бы.


"Странности при записи в файл"
Отправлено DeadMustdie , 03-Июн-06 21:15 
>Не знаю, кто в танке, но под такие дела пишутся ТЕСТЫ. Чудес
>компьютеры не творят, поэтому ТЕСТЫ + отладчик (если нужно) решают ЛЮБЫЕ
>проблемы и разъясняют что, где не так, как хотелось бы.

Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
программировать будете, через годик-другой оптимизму в части тестов и отладчиков
у Вас должно поубавиться.

2 original poster:

По существу вопроса: для ловли редко возникающих тараканов люди придумали
assert() + core dump + таки отладчик, но по дампу. По крайней мере, позволит
понять, как программа дошла до жизни такой.

Если чисто прозекторские меры (над уже хладным трупом) не помогут, можно
попробовать трассировочкий. Ну и мозги, и /dev/hands. Вряд ли кто-то из
местной публики будет плотно сидеть над Вашей программой, так что в такой
мерзкой ситуации с гарантией только самому выгрести можно.

Из чистой паранойи я бы посоветовал ещё под valgrind пускануть.
Если причина тупая, типа порчи памяти - само поймается.


"Странности при записи в файл"
Отправлено zkrvova , 05-Июн-06 10:44 
>>Не знаю, кто в танке, но под такие дела пишутся ТЕСТЫ. Чудес
>>компьютеры не творят, поэтому ТЕСТЫ + отладчик (если нужно) решают ЛЮБЫЕ
>>проблемы и разъясняют что, где не так, как хотелось бы.
>
>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>у Вас должно поубавиться.
>
>2 original poster:
>
>По существу вопроса: для ловли редко возникающих тараканов люди придумали
>assert() + core dump + таки отладчик, но по дампу. По крайней
>мере, позволит
>понять, как программа дошла до жизни такой.
>
>Если чисто прозекторские меры (над уже хладным трупом) не помогут, можно
>попробовать трассировочкий. Ну и мозги, и /dev/hands. Вряд ли кто-то из
>местной публики будет плотно сидеть над Вашей программой, так что в такой
>
>мерзкой ситуации с гарантией только самому выгрести можно.
>
>Из чистой паранойи я бы посоветовал ещё под valgrind пускануть.
>Если причина тупая, типа порчи памяти - само поймается.


Я не думаю что ктото будет плотно сидеть над моей програмой. Я ждал совета как поступисть и с помощью каких средств, т.к. я ещё плохо знаком с разными системами отладки в Линуксе.
Если дадите ссылки на то где можно почитать про отладку буду благодарен!


"Странности при записи в файл"
Отправлено SnaiL , 05-Июн-06 11:22 
>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>у Вас должно поубавиться.
>

Возможно, однако за 5 лет такая практика не подводила :-) Наверное я чего-то не знаю.


"Странности при записи в файл"
Отправлено guest , 09-Июн-06 01:28 
>>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>>у Вас должно поубавиться.
>>
>
>Возможно, однако за 5 лет такая практика не подводила :-) Наверное я
>чего-то не знаю.

и даже в данной ситуации? я вот не представляю себе, какой тут стоит написать тест. Куда и как втыкать вызов `execlp("gdb", asprintf ("--pid=%d", parent_pid), NULL);' я могу понять, а вот какой бы тест написать...


"Странности при записи в файл"
Отправлено zkrvova , 09-Июн-06 14:29 
>>>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>>>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>>>у Вас должно поубавиться.
>>>
>>
>>Возможно, однако за 5 лет такая практика не подводила :-) Наверное я
>>чего-то не знаю.
>
>и даже в данной ситуации? я вот не представляю себе, какой тут
>стоит написать тест. Куда и как втыкать вызов `execlp("gdb", asprintf ("--pid=%d",
>parent_pid), NULL);' я могу понять, а вот какой бы тест написать...
>


Вот и я непредставляю. Поэтому и прошу совета.


"Странности при записи в файл"
Отправлено MaximKuznetsov , 09-Июн-06 11:02 
Если не затруднит, приведите нагенерённый асм. код для

    syslog(LOG_INFO,"2.2 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);
                    fprintf(stream, "%.2f", 0);
    syslog(LOG_INFO,"3.2 - Write access_bonus for user %s = %f",t_data[a].login, t_data[a].access_bonus);

и файл который получился после записи.

Просто есть подозрение, что надо было правильно привести типы :
fprintf(stream, "%.2f", (float)0.0);

например строчка printf("%.2g",0) совершенно точно выдаёт мусор.

p.s. если используете printf/scanf функции то компилятору желательно дать флажок
-Wformat чтобы он ругался при явном несоответсвии форматной строки и аргументов


"Странности при записи в файл"
Отправлено zkrvova , 09-Июн-06 14:28 
>Если не затруднит, приведите нагенерённый асм. код для
>
>    syslog(LOG_INFO,"2.2 - Write access_bonus for user %s =
>%f",t_data[a].login, t_data[a].access_bonus);
>            
>        fprintf(stream, "%.2f", 0);
>
>    syslog(LOG_INFO,"3.2 - Write access_bonus for user %s =
>%f",t_data[a].login, t_data[a].access_bonus);
>
>и файл который получился после записи.
>
>Просто есть подозрение, что надо было правильно привести типы :
>fprintf(stream, "%.2f", (float)0.0);
>
>например строчка printf("%.2g",0) совершенно точно выдаёт мусор.
>
>p.s. если используете printf/scanf функции то компилятору желательно дать флажок
>-Wformat чтобы он ругался при явном несоответсвии форматной строки и аргументов


Подскажите как сгенерить asm код и я приведу.

Но странно что обычно пишится нормальный 0, но только иногда мусор.


"Странности при записи в файл"
Отправлено MaximKuznetsov , 09-Июн-06 14:45 
для генерации asm - добавить ключ -S при компиляции

заодно уж (с этого надо начинать) скажите, что за система (uname -a),
версию компилятора (gcc -v) и строчку его вызова


"Странности при записи в файл"
Отправлено zkrvova , 09-Июн-06 15:12 
>для генерации asm - добавить ключ -S при компиляции
>
>заодно уж (с этого надо начинать) скажите, что за система (uname -a),
>
>версию компилятора (gcc -v) и строчку его вызова


Linux 2.4.20-8 #1 Thu Mar 13 16:42:56 EST 2003 i686 i686 i386 GNU/Linux

Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)


Строчка вызова:
gcc ./trafic.c


Вот кусок кода:

    addl    $32, %esp
    subl    $4, %esp
    pushl    $0
    pushl    $.LC25             - это строка "%.2f"
    pushl    stream
    call    fprintf
    addl    $16, %esp
    subl    $12, %esp
    movl    -12(%ebp), %eax


fprintf(stream, "%.2f", 0);


"Странности при записи в файл"
Отправлено guest , 10-Июн-06 01:38 
>>для генерации asm - добавить ключ -S при компиляции
>>
...
>Вот кусок кода:
>
> addl $32, %esp
> subl $4, %esp
> pushl $0
> pushl $.LC25          
>   - это строка "%.2f"
> pushl stream
> call fprintf
> addl $16, %esp
> subl $12, %esp
> movl -12(%ebp), %eax

бинго!
развлечения для и ради, можете попробовать прогнать такой код:
#include <stdio.h>

int main ()
{
    printf ("%f\n", 0, 0x3fe70a3d);
    return 0;
}


"Странности при записи в файл"
Отправлено zkrvova , 13-Июн-06 17:26 
>>>для генерации asm - добавить ключ -S при компиляции
>>>
>...
>>Вот кусок кода:
>>
>> addl $32, %esp
>> subl $4, %esp
>> pushl $0
>> pushl $.LC25          
>>   - это строка "%.2f"
>> pushl stream
>> call fprintf
>> addl $16, %esp
>> subl $12, %esp
>> movl -12(%ebp), %eax
>
>бинго!
>развлечения для и ради, можете попробовать прогнать такой код:
>#include <stdio.h>
>
>int main ()
>{
> printf ("%f\n", 0, 0x3fe70a3d);
> return 0;
>}


        .file   "test.c"
        .section        .rodata
.LC0:
        .string "%f\n"
        .text
.globl main
        .type   main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        subl    $4, %esp
        pushl   $1072106045
        pushl   $0
        pushl   $.LC0
        call    printf
        addl    $16, %esp
        movl    $0, %eax
        leave
        ret
.Lfe1:
        .size   main,.Lfe1-main
        .ident  "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

А что бинго? Что нашли?


"Странности при записи в файл"
Отправлено guest , 14-Июн-06 02:29 
>А что бинго? Что нашли?

компилируй свою программу с -Wall, тебе gcc расскажет всё. ;) Вообще, возьми это за правило: экономит время до жути.
Если вкратце, на x86 sizeof (float) == 8, а ты в printf'е кладёшь всего четыре (sizeof (int)) байта нулей, то есть младшие байты мантиссы флоата. Ну а printf-то об этом ничего не знает, и берёт из стека все восемь байт. А что там за старшие байты, предсказать сложно. Видать при определённых обстоятельствах ветвление идёт несколько иначе (в твоём коде, или в библиотечном), и в результате под твоими нулями оказывается константа, которую я в коде продемонстрировал.


"Странности при записи в файл"
Отправлено zkrvova , 14-Июн-06 09:55 
>>А что бинго? Что нашли?
>
>компилируй свою программу с -Wall, тебе gcc расскажет всё. ;) Вообще, возьми
>это за правило: экономит время до жути.
>Если вкратце, на x86 sizeof (float) == 8, а ты в printf'е
>кладёшь всего четыре (sizeof (int)) байта нулей, то есть младшие байты
>мантиссы флоата. Ну а printf-то об этом ничего не знает, и
>берёт из стека все восемь байт. А что там за старшие
>байты, предсказать сложно. Видать при определённых обстоятельствах ветвление идёт несколько иначе
>(в твоём коде, или в библиотечном), и в результате под твоими
>нулями оказывается константа, которую я в коде продемонстрировал.


Большое спасибо!!!


"Странности при записи в файл"
Отправлено Ф , 14-Июн-06 13:11 
>Если вкратце, на x86 sizeof (float) == 8

Это с каких пор на x86 sizeof(float) равно 8 ???

Типы access_bonus из структуры t_data до сих пор загадка.
Также как и тип f_tmp.

Посмотрите файл не программно, а через консоль или редактор.
Какой разделитель записывается . или , . Может какие проблемы с locale.


"Странности при записи в файл"
Отправлено guest , 14-Июн-06 23:18 
>>Если вкратце, на x86 sizeof (float) == 8
>
>Это с каких пор на x86 sizeof(float) равно 8 ???

с каких, не знаю, но:

fprintf ("%d\n", sizeof (float));

выдало мне 8 на i686-pc-linux-gnu ;)
Сам удивился.


"Странности при записи в файл"
Отправлено michelnok , 15-Июн-06 11:46 
>с каких, не знаю, но:
>
>fprintf ("%d\n", sizeof (float));
>
>выдало мне 8 на i686-pc-linux-gnu ;)
>Сам удивился.

Выдало 4

[mchelnokov@workstation Projects]$ uname -op
i686 GNU/Linux


"Странности при записи в файл"
Отправлено guest , 16-Июн-06 00:43 
>>с каких, не знаю, но:
>>
>>fprintf ("%d\n", sizeof (float));
>>
>>выдало мне 8 на i686-pc-linux-gnu ;)
>>Сам удивился.
>
>Выдало 4

это мои тараканы :).
точно 4.


"Странности при записи в файл"
Отправлено chip , 16-Июн-06 16:31 
>>>Если вкратце, на x86 sizeof (float) == 8
>>
>>Это с каких пор на x86 sizeof(float) равно 8 ???
>
>с каких, не знаю, но:
>
>fprintf ("%d\n", sizeof (float));
>
>выдало мне 8 на i686-pc-linux-gnu ;)

Интересно, что оно вообще что-то выдало, учитывая то что первый аргумент fprintf - FILE *

>Сам удивился.

А мы то как удивились.



"Странности при записи в файл"
Отправлено michelnok , 15-Июн-06 11:38 
>Если вкратце, на x86 sizeof (float) == 8, а ты в printf'е
>кладёшь всего четыре (sizeof (int)) байта нулей, то есть младшие байты

Эээ... А с каких пор %f в printf стал означать float, а не double? ;-)