Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но иногда в файл записывается какоето левое значение. Вот кусок кода:
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.
Почему? Я понять пока немогу.Причём происходит это не всегда а изредка.
Что делать? подскажите!
Спасибо!
>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>
>Что делать? подскажите!
>Спасибо!Пожалуйста ;-)))
А в файле то у тебя что записалось????
Потому как то что ты читаешь из файла и то что там есть - это две большие разницы.И уж как минимум надо(думаю) ставить строку формата чтения, точно такой же как и у формата записи.
А вообще у тебя как, на каждого пользователя по файлу что ли??? или ты еще как то хитро позиционируешь??? просто здесь не показал...
>>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>
>
>>
>>Что делать? подскажите!
>>Спасибо!
>
>Пожалуйста ;-)))
>А в файле то у тебя что записалось????
>Потому как то что ты читаешь из файла и то что там
>есть - это две большие разницы.То и записалось, то что выдаёт то там и есть т.е. 72 с копейками.
Но каждый раз разные значения бывают. РАньше было 20 с чемто, а теперь 72.>И уж как минимум надо(думаю) ставить строку формата чтения, точно такой же
>как и у формата записи.Так строка формата отличается только количеством цифр после запятой, недумаю что из за этого добавляются целые числа.
>А вообще у тебя как, на каждого пользователя по файлу что ли???
>или ты еще как то хитро позиционируешь??? просто здесь не показал...
>
на каждого юзера по каталогу и в коталоге файлы с данными. Юзеры обрабатываются по очереди, т.е. сначала все данные одного обработались, потом пошли другие.
>>>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>>>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>>
>>>
>на каждого юзера по каталогу и в коталоге файлы с данными. Юзеры
ужас какой!!!!>обрабатываются по очереди, т.е. сначала все данные одного обработались, потом пошли
>другие.
Слушай а у тебя приложение не многопоточное???вообще мне не нравиться твое глобальное stream, ты вызываешь некую функцию open_file
а потом начинаешь записывать в некий stream, где гаранти что ее кто-нибудь в этот момент не вызовет, и не поменяет нафиг, а может откуда нибудь еще в этот стрим пишеться...Кстати в этот файл может только это приложение писать???
>>>>Моя программа считает трафик и соответственно деньги. Данные хранятся в файлах. Но
>>>>иногда в файл записывается какоето левое значение. Вот кусок кода:
>>>>
>>>
>
>>
>>на каждого юзера по каталогу и в коталоге файлы с данными. Юзеры
>ужас какой!!!!
>
>>обрабатываются по очереди, т.е. сначала все данные одного обработались, потом пошли
>>другие.
>
>
>Слушай а у тебя приложение не многопоточное???
>
>вообще мне не нравиться твое глобальное stream, ты вызываешь некую функцию open_file
>
>а потом начинаешь записывать в некий stream, где гаранти что ее кто-нибудь
>в этот момент не вызовет, и не поменяет нафиг, а может
>откуда нибудь еще в этот стрим пишеться...
>
>Кстати в этот файл может только это приложение писать???
В этот файл только эта прога может писать.
Другая из этого файла читает.Данная прога вызывается 1 раз в минуту и она не многопоточная ,она просто в цикле переберает данные и всё.
так ты это, смотри что возвращает fprintf и пиши результат в лог..
>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>
Хорошая идея, попробую.
>>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>>
>
>
>Хорошая идея, попробую.А отладчиком воспользоваться - не судьба?
>>>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>>>
>>
>>
>>Хорошая идея, попробую.
>
>А отладчиком воспользоваться - не судьба?
Для тех кто в танке - читай с начала: "Такое происходит изредка"
В отладчике таких проблем небыло замечено чтолько после месяца работы.
>>>>так ты это, смотри что возвращает fprintf и пиши результат в лог..
>>>>
>>>
>>>
>>>Хорошая идея, попробую.
>>
>>А отладчиком воспользоваться - не судьба?
>
>
>Для тех кто в танке - читай с начала: "Такое происходит изредка"
>
>В отладчике таких проблем небыло замечено чтолько после месяца работы.Не знаю, кто в танке, но под такие дела пишутся ТЕСТЫ. Чудес компьютеры не творят, поэтому ТЕСТЫ + отладчик (если нужно) решают ЛЮБЫЕ проблемы и разъясняют что, где не так, как хотелось бы.
>Не знаю, кто в танке, но под такие дела пишутся ТЕСТЫ. Чудес
>компьютеры не творят, поэтому ТЕСТЫ + отладчик (если нужно) решают ЛЮБЫЕ
>проблемы и разъясняют что, где не так, как хотелось бы.Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
программировать будете, через годик-другой оптимизму в части тестов и отладчиков
у Вас должно поубавиться.2 original poster:
По существу вопроса: для ловли редко возникающих тараканов люди придумали
assert() + core dump + таки отладчик, но по дампу. По крайней мере, позволит
понять, как программа дошла до жизни такой.Если чисто прозекторские меры (над уже хладным трупом) не помогут, можно
попробовать трассировочкий. Ну и мозги, и /dev/hands. Вряд ли кто-то из
местной публики будет плотно сидеть над Вашей программой, так что в такой
мерзкой ситуации с гарантией только самому выгрести можно.Из чистой паранойи я бы посоветовал ещё под valgrind пускануть.
Если причина тупая, типа порчи памяти - само поймается.
>>Не знаю, кто в танке, но под такие дела пишутся ТЕСТЫ. Чудес
>>компьютеры не творят, поэтому ТЕСТЫ + отладчик (если нужно) решают ЛЮБЫЕ
>>проблемы и разъясняют что, где не так, как хотелось бы.
>
>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>у Вас должно поубавиться.
>
>2 original poster:
>
>По существу вопроса: для ловли редко возникающих тараканов люди придумали
>assert() + core dump + таки отладчик, но по дампу. По крайней
>мере, позволит
>понять, как программа дошла до жизни такой.
>
>Если чисто прозекторские меры (над уже хладным трупом) не помогут, можно
>попробовать трассировочкий. Ну и мозги, и /dev/hands. Вряд ли кто-то из
>местной публики будет плотно сидеть над Вашей программой, так что в такой
>
>мерзкой ситуации с гарантией только самому выгрести можно.
>
>Из чистой паранойи я бы посоветовал ещё под valgrind пускануть.
>Если причина тупая, типа порчи памяти - само поймается.
Я не думаю что ктото будет плотно сидеть над моей програмой. Я ждал совета как поступисть и с помощью каких средств, т.к. я ещё плохо знаком с разными системами отладки в Линуксе.
Если дадите ссылки на то где можно почитать про отладку буду благодарен!
>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>у Вас должно поубавиться.
>Возможно, однако за 5 лет такая практика не подводила :-) Наверное я чего-то не знаю.
>>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>>у Вас должно поубавиться.
>>
>
>Возможно, однако за 5 лет такая практика не подводила :-) Наверное я
>чего-то не знаю.и даже в данной ситуации? я вот не представляю себе, какой тут стоит написать тест. Куда и как втыкать вызов `execlp("gdb", asprintf ("--pid=%d", parent_pid), NULL);' я могу понять, а вот какой бы тест написать...
>>>Вы, батенька, баальшой оптимист. Я Вам даже немножко завидую. Если плотно
>>>программировать будете, через годик-другой оптимизму в части тестов и отладчиков
>>>у Вас должно поубавиться.
>>>
>>
>>Возможно, однако за 5 лет такая практика не подводила :-) Наверное я
>>чего-то не знаю.
>
>и даже в данной ситуации? я вот не представляю себе, какой тут
>стоит написать тест. Куда и как втыкать вызов `execlp("gdb", asprintf ("--pid=%d",
>parent_pid), NULL);' я могу понять, а вот какой бы тест написать...
>
Вот и я непредставляю. Поэтому и прошу совета.
Если не затруднит, приведите нагенерённый асм. код для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 чтобы он ругался при явном несоответсвии форматной строки и аргументов
>Если не затруднит, приведите нагенерённый асм. код для
>
> 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, но только иногда мусор.
для генерации asm - добавить ключ -S при компиляциизаодно уж (с этого надо начинать) скажите, что за система (uname -a),
версию компилятора (gcc -v) и строчку его вызова
>для генерации asm - добавить ключ -S при компиляции
>
>заодно уж (с этого надо начинать) скажите, что за система (uname -a),
>
>версию компилятора (gcc -v) и строчку его вызова
Linux 2.4.20-8 #1 Thu Mar 13 16:42:56 EST 2003 i686 i686 i386 GNU/LinuxReading 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);
>>для генерации 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;
}
>>>для генерации 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)"А что бинго? Что нашли?
>А что бинго? Что нашли?компилируй свою программу с -Wall, тебе gcc расскажет всё. ;) Вообще, возьми это за правило: экономит время до жути.
Если вкратце, на x86 sizeof (float) == 8, а ты в printf'е кладёшь всего четыре (sizeof (int)) байта нулей, то есть младшие байты мантиссы флоата. Ну а printf-то об этом ничего не знает, и берёт из стека все восемь байт. А что там за старшие байты, предсказать сложно. Видать при определённых обстоятельствах ветвление идёт несколько иначе (в твоём коде, или в библиотечном), и в результате под твоими нулями оказывается константа, которую я в коде продемонстрировал.
>>А что бинго? Что нашли?
>
>компилируй свою программу с -Wall, тебе gcc расскажет всё. ;) Вообще, возьми
>это за правило: экономит время до жути.
>Если вкратце, на x86 sizeof (float) == 8, а ты в printf'е
>кладёшь всего четыре (sizeof (int)) байта нулей, то есть младшие байты
>мантиссы флоата. Ну а printf-то об этом ничего не знает, и
>берёт из стека все восемь байт. А что там за старшие
>байты, предсказать сложно. Видать при определённых обстоятельствах ветвление идёт несколько иначе
>(в твоём коде, или в библиотечном), и в результате под твоими
>нулями оказывается константа, которую я в коде продемонстрировал.
Большое спасибо!!!
>Если вкратце, на x86 sizeof (float) == 8Это с каких пор на x86 sizeof(float) равно 8 ???
Типы access_bonus из структуры t_data до сих пор загадка.
Также как и тип f_tmp.Посмотрите файл не программно, а через консоль или редактор.
Какой разделитель записывается . или , . Может какие проблемы с locale.
>>Если вкратце, на x86 sizeof (float) == 8
>
>Это с каких пор на x86 sizeof(float) равно 8 ???с каких, не знаю, но:
fprintf ("%d\n", sizeof (float));
выдало мне 8 на i686-pc-linux-gnu ;)
Сам удивился.
>с каких, не знаю, но:
>
>fprintf ("%d\n", sizeof (float));
>
>выдало мне 8 на i686-pc-linux-gnu ;)
>Сам удивился.Выдало 4
[mchelnokov@workstation Projects]$ uname -op
i686 GNU/Linux
>>с каких, не знаю, но:
>>
>>fprintf ("%d\n", sizeof (float));
>>
>>выдало мне 8 на i686-pc-linux-gnu ;)
>>Сам удивился.
>
>Выдало 4это мои тараканы :).
точно 4.
>>>Если вкратце, на x86 sizeof (float) == 8
>>
>>Это с каких пор на x86 sizeof(float) равно 8 ???
>
>с каких, не знаю, но:
>
>fprintf ("%d\n", sizeof (float));
>
>выдало мне 8 на i686-pc-linux-gnu ;)Интересно, что оно вообще что-то выдало, учитывая то что первый аргумент fprintf - FILE *
>Сам удивился.
А мы то как удивились.
>Если вкратце, на x86 sizeof (float) == 8, а ты в printf'е
>кладёшь всего четыре (sizeof (int)) байта нулей, то есть младшие байтыЭээ... А с каких пор %f в printf стал означать float, а не double? ;-)