title: vfprintf() throws SegFault - but input is well-defined?
body: <p>I am given the following function in a program:</p>
  
  <pre><code>void log(char* arg1, ...)
  {
      time_t      t;
      struct tm   *tm;
      va_list     args;
      char        *fmt;
      char        curtime[TIME_STR_SIZE];
      FILE        *fd;
  
      va_start(args, arg1); // linux stdarg va_start req 2 args - va_lilst, parm_n
  
  
      fmt = va_arg(args, char*);
  
      if (lfd == NULL)
          fd = stderr;
      else
          fd = lfd;
  
     (void) time(&amp;t);
     tm = localtime(&amp;t);
  
     sprintf(curtime, "%02d.%02d.%d, %02d:%02d:%02d", tm-&gt;tm_mday, tm-&gt;tm_mon+1, tm-&gt;tm_year+1900, tm-&gt;tm_hour, tm-&gt;tm_min, tm-&gt;tm_sec);
  
      fprintf(fd, "%s: ", curtime);
      vfprintf(fd, arg1, args);
      fprintf(fd, "\n");
      fflush(fd);
  
      va_end(args);
  }
  </code></pre>
  
  <p>obviously it takes a list of input parameters and writes them to a file.</p>
  
  <p>But running this part of the code throws a segmentation fault which I have backtracked to vfprintf:</p>
  
  <pre><code>(gdb) backtrace
  #0  0x00007ffff4799db2 in __strlen_sse2 () from /lib64/libc.so.6
  #1  0x00007ffff476220d in vfprintf () from /lib64/libc.so.6
  #2  0x0000000000401b03 in log (arg1=0x40529d "%s gestartet: PID = %d") at logging.c:73
  #3  0x00000000004045d4 in main (argc=10, argv=0x7fffffffdc98) at abgleich.c:589
  </code></pre>
  
  <p>While running gdb and printing the parameters is fine:</p>
  
  <pre><code>(gdb) print fd
  $9 = (FILE *) 0x607010
  (gdb) print fmt
  $10 = 0x7fffffffe1a7 "/srv/workspace/abgleich/abgleich"
  (gdb) print args
  $11 = {{gp_offset = 16, fp_offset = 48, overflow_arg_area = 0x7fffffffda10, reg_save_area = 0x7fffffffd950}}
  </code></pre>
  
  <p>I am curious why the segmentation fault is thrown as it looks as a well-defined input in this case.</p>
  
  <p>The calling part of the function is following:</p>
  
  <pre><code>log("%s gestartet: PID = %d", argv[0], getpid());
  </code></pre>
  
  <p>Edit:</p>
  
  <p>I have rewritten using va_copy in the following way:</p>
  
  <pre><code> va_start(args, arg1); // linux stdarg va_start req 2 args - va_lilst, parm_n
   va_copy(c_args, args);
  
   if (lfd == NULL)
       fd = stderr;
   else
       fd = lfd;
  
  (void) time(&amp;t);
  tm = localtime(&amp;t);
  
   /* strftime(curtime, TIME_STR_SIZE, "%d.%m.%y, %H:%M:%S\0", time_ptr); */
  sprintf(curtime, "%02d.%02d.%d, %02d:%02d:%02d", tm-&gt;tm_mday, tm-&gt;tm_mon+1, tm-&gt;tm_year+1900, tm-&gt;tm_hour, tm-&gt;tm_min, tm-&gt;tm_sec);
   fprintf(fd, "%s: ", curtime);
   vfprintf(fd, arg1, c_args);
   fprintf(fd, "\n");
   fflush(fd);
  
   va_end(args);
  </code></pre>