Question

Ceci est le code:

void i_log_ (int error, const char * file, int line, const char * fmt, ...)
{
     /* Get error description */
     char * str_err = get_str_error (errno);
     remove_trailing_newl (str_err);

     /* Format string and parameters */
     char message [1024];
     va_list ap;
     va_start (ap, fmt);
     vsprintf (message, fmt, ap);
     va_end (ap);

     /* Get time */
     time_t t = time (NULL);
     char stime [64];
     char * temp = ctime (&t);
     strncpy (stime, temp, sizeof stime - 1);
     remove_trailing_newl (stime);

     FILE * log;


#ifdef __WIN32__
#else
# ifdef P_LISTENER
     log = fopen (I_LOG_FILE, "a+b");
     flock (fileno (log), LOCK_EX);
# else /* shared file descriptor of log, lock before opening */
     pthread_mutex_lock (& mutex);
     log = fopen (I_LOG_FILE, "a+b");
# endif
#endif

     if (log) {
          if (error)
               fprintf (log, ERR_FORMAT, stime, file, line, str_err, message);
          else
               fprintf (log, ERR_FORMAT_NO_ERRNO, stime, file, line, message);
     }

#ifdef __WIN32__
     free (str_err);
#else
# ifdef P_LISTENER
     flock (fileno (log), LOCK_UN);
     fclose (log);
# else
     fclose (log);
     pthread_mutex_unlock (& mutex);
# endif
#endif
     return;
}

Bien qu'il existe un mécanisme de verrouillage, dans ce cas, la fonction n'est pas appelée simultanément, donc je pense que ce n'est pas le problème. Cependant, le programme reçoit un SIGABRT:

[...]
(gdb) c
Continuing.

Program received signal SIGHUP, Hangup. // It's OK, I sent this.
0x00dee416 in __kernel_vsyscall ()
(gdb) c
Continuing.

Program received signal SIGABRT, Aborted.
0x00dee416 in __kernel_vsyscall ()
(gdb) up
#1  0x0013ae71 in raise () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#2  0x0013e34e in abort () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#3  0x00171577 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#4  0x0017b961 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#5  0x0017d28b in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#6  0x0018041d in free () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#7  0x0019b0d2 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#8  0x0019b3c5 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#9  0x00199a9f in localtime () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#10 0x00199951 in ctime () from /lib/i386-linux-gnu/libc.so.6
(gdb) up
#11 0x08049634 in i_log_ (error=0, file=0x804b17d "src/group.c", line=53, fmt=0x804b128 "Setting up new configuration: listener type: %s, number: %d, http-log: %s, port: %d.") at src/error.c:42
42       char * temp = ctime (&t);
(gdb) print temp
$1 = 0x260000 ""
(gdb) print t
$2 = 1329935482
(gdb) print &t
$3 = (time_t *) 0xbff8a5b8
(gdb) 

Je n'ai aucune idée. ctime Renvoie une chaîne vide et la page de l'homme ne mentionne pas ce cas. Et à y penser, je ne comprends pas pourquoi il renverrait une chaîne vide et ce qui ne va pas avec ce code.

Toute aide est appréciée.

Était-ce utile?

La solution

ctime ne renvoie pas une chaîne vide. Il n'est pas encore revenu du tout, car il s'est écrasé en essayant de faire son travail.

L'accident est à l'intérieur free(), donc vous corrompez probablement la mémoire à un moment donné avant d'appeler ctime(). Si vous utilisez une plate-forme prise en charge, essayez d'utiliser un outil comme Valgrind pour vérifier vos accès de mémoire.

Autres conseils

Puisque l'accident se déroule à l'intérieur ctime() Et le pointeur que vous passez est valide, le problème est probable que vous ayez déjà piétiné à sortir des limites avec de la mémoire (il y a free() Dans la trace de pile) ailleurs et le problème ne se manifeste que ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top