localtime () сбой с ошибкой сегментации в c

У вас есть проблемы с выяснением причины этого.

Вот бит кода:

    #include <time.h>
time_t now;
struct tm *mytime;
char yyyy[5];
char mm[3];
char dd[3];
char mname[10];
if(time(&now)!=(time_t)(-1))
{
    mytime=localtime(&now);
    strftime(yyyy, sizeof(yyyy), "%Y", mytime);
    strftime(mm, sizeof(mm), "%m", mytime);
    strftime(dd, sizeof(dd), "%d", mytime);
    strftime(mname, sizeof(mname), "%B", mytime);
}

Вылетает на localtime строке:

Segmentation fault (core dumped)

Любые идеи?


person Mannix    schedule 19.03.2014    source источник
comment
То же самое. На моем ящике нет дампа ядра (gcc 4.8.1 / glibc 2.17 на Lubuntu 13.10).   -  person Mike Holt    schedule 20.03.2014
comment
Каковы доказательства того, что localtime() разбился?   -  person chux - Reinstate Monica    schedule 20.03.2014
comment
Доказательство состоит в том, что я вставил несколько printf операторов, чтобы изолировать строку в коде, вызвавшую ошибку.   -  person Mannix    schedule 20.03.2014
comment
1) Вместо того, чтобы обсуждать доказательства, опубликуйте их: используемый код и соответствующий вывод. При добавлении printf() могут возникнуть ошибки из-за printf(). 2) Рассмотрим struct tm mytime; mytime = *localtime(&now); if (0==strftime(yyyy, sizeof(yyyy), "%Y", &mytime)) Handle_Error();   -  person chux - Reinstate Monica    schedule 20.03.2014


Ответы (2)


У меня пример кода работает нормально. Разместите свой полный код? Или сократите свой пример до минимально возможного, который все еще воспроизводит проблему. И запустите gdb на своем ядре 'gdb -c a.core a.out' и получите обратную трассировку (bt).

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

struct tm * localtime (const time_t * время)

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

От: http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html

При поиске файлов ядра:

См. Также дамп ядра, но файл ядра не в текущем каталог?

Убедитесь, что система может записывать файл ядра.
* для меня на одном примере системы ununtu ulimit -c показал 0 *

ulimit -c unlimited

Проверьте, какой узор использовался, и измените узор на простой или другой.

cat /proc/sys/kernel/core_pattern
#sysctl -w kernel.core_pattern=core

Найдите несколько распространенных мест и посмотрите в / var / log / messages:

ls /var/crash /var/cache/abrt /var/spool/abrt/ /tmp/*core*
tail /var/log/messages

В ubuntu проверьте конфигурацию службы аппорта и файлы init / rcfiles:

find /etc/ |grep appo
person gaoithe    schedule 19.03.2014
comment
Хотя он сказал, что создал файл ядра, его там нет. Какие флаги компилятора мне нужны, чтобы он создавал основной файл с полезными данными? - person Mannix; 20.03.2014
comment
Компилятор не контролирует создание или расположение файла ядра. Это системная настройка. Ты на linux? Какой вид ОС и версию вы используете? - person gaoithe; 20.03.2014
comment
Посмотрите в / var / crash или / var / cache / abrt или. / var / spool / abrt / или другое в зависимости от конфигурации вашей системы. См. Также stackoverflow.com/questions/2065912/ - person gaoithe; 20.03.2014
comment
Нет, его нет ни в одном из этих каталогов. $ uname -a Linux marple.physast 3.2.0-60-generic # 91-Ubuntu SMP среда, 19 февраля, 03:54:44 UTC 2014 x86_64 x86_64 x86_64 GNU / Linux - person Mannix; 20.03.2014
comment
Хм. Ubuntu. Grep для конфигурации corefiles в / etc и в ядре. Может быть, начать с find /etc -name "*core*" и find /etc -type f -exec grep core {} +. Загляните внутрь найденных файлов. Есть какие-нибудь подсказки о местонахождении или названии? Также проверьте свой ulimit -c, как и в другом вопросе о стеке. - person gaoithe; 20.03.2014
comment
Ищите основной шаблон в ядре. cat /proc/sys/kernel/core_pattern лежат ли какие-нибудь файлы ядра, соответствующие этому шаблону? Перед тем, как запустить прогу, которая вылетает, поменяйте шаблон на простой: sysctl -w kernel.core_pattern=core. Это может переопределить шаблон ядра и получить дампы ядра, созданные в текущем каталоге. - person gaoithe; 20.03.2014

Это может быть или не быть чем-то близким к вашей проблеме? По-прежнему недостаточно информации, чтобы быть уверенным в том, что вы делаете. Я бы подумал, что проблема не в локальном времени, но где-то в printfs есть проблемы. . .

Как вы составляете свой проект? g ++ или gcc?

Вы можете напечатать строку ?? (в отличие от строки ptr) Что такое строка в вашем контексте?

Здесь 1 проблема:

fprintf(stdout,"# Single electron capture cross sections, %s state-selective\n",res);

Если строка - это typedef a char [], тогда было бы лучше передать указатель на нее в func args?

Компиляция вашего образца с некоторыми предположениями и добавлением отладки (-g3):

gcc -g3 stackoverflow_localtime_crash.c -o socrash

./socrash 

# Single electron capture cross sections, RESSTRING state-selective
# Magic number=20032014, 20 March 2014, 
# Single electron capture cross sections, RESSTRING state-selective
# ^0+ +  -> ^-1+ + ^+
# Method=MCLZ
#  et al. 2014, to be submitted
# ----------------------------------------------------------------------------
# Energy        Cross sections (10^-16 cm^2)
# (eV/u)        LABELSTRING                     �H���u�j 

* За строкой res следует еще больше JUNK, которую нельзя передать в стек и распечатать *

Segmentation fault (core dumped)

gdb -c core socrash 

Core was generated by `./socrash'.
Program terminated with signal 11, Segmentation fault.
[New process 10298]
#0  0xb770e713 in strlen () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0  0xb770e713 in strlen () from /lib/tls/i686/cmov/libc.so.6
#1  0xb76da6d9 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
#2  0xb76e0b9f in fprintf () from /lib/tls/i686/cmov/libc.so.6
#3  0x08048a42 in prtcsheader (cs=0xbf9e907c, labels=0xbf9e90bc, res=0xbf9e90a8 "RESSTRING") at stackoverflow_localtime_crash.c:66
#4  0x08048b36 in main (argc=Cannot access memory at address 0x0
) at stackoverflow_localtime_crash.c:80
(gdb) list
64      fprintf(stdout,"%-15s","# (eV/u)");
65      for(i=0;labels[i]!=NULL;i++)
66          fprintf(stdout,"\t%-14s",labels[i]);
67      fprintf(stdout,"\t%-14s","Total");
68  
69  return 0;
(gdb) 

* см. строку 66, там тоже проблема * вполне может быть так, как я объявил строку :-P

66          fprintf(stdout,"\t%-14s",labels[i]);

* Если вы можете найти файл ядра самостоятельно, это будет большим подспорьем !!! *

Если вы не можете найти ядро, возможно, вы могли бы использовать ltrace. Запустите strace, чтобы получить трассировку всех системных вызовов, которые выполняет процесс. Запустите ltrace, чтобы получить трассировку всех вызовов библиотеки, которые выполняет процесс.

Пытаться:

strace ls

ltrace ls

В моем примере сбоя:

ltrace ./socrash 1>stdout.log 2>socrash_ltrace.log
less socrash_ltrace.log 
person gaoithe    schedule 20.03.2014
comment
string is char * $ gcc --version gcc (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3 Параметры компилятора: -Wall -std = gnu99 - person Mannix; 21.03.2014
comment
labels - это массив строк с завершающим нулем, то есть char **. Итак, labels это string * или char **. Но, как я уже сказал, при вызове localtime() происходит сбой. Я вставил в код несколько операторов printf, чтобы определить, какая строка привела к ошибке сегментации. Это было localtime(). - person Mannix; 21.03.2014
comment
Учитывая всю информацию, вызовы localtime () выглядят нормально. Поведение printfs рядом с ошибкой seg может не указать вам место ошибки. Все, что printf помещает в выходной буфер, может не отображаться. Или происходит что-то плохое, но неуловимое, что приводит к ошибке сегментирования чуть позже в коде. Был ли у вас \ n в конце всех ваших отладочных printfs? У вас ведь нет нескольких потоков? У нас нет точной информации, поэтому мы подозреваем, что сейчас не местное время. Вы пробовали ltrace? Вы проверяли, что показывает ulimit -c? Найти ядро? Добавление параметров отладки во время компиляции делает ядро ​​более полезным. - person gaoithe; 21.03.2014