3

I am using vsnprintf in a machine and it's not giving error but when i ran exact code spinet it's giving me error.

My machine where i am getting error on machine

Linux localhost 3.14.1-1-ARCH #1 SMP PREEMPT Mon Apr 14 20:40:47 CEST 2014 x86_64 GNU/Linux

Machine where i am not getting any error about this.

Linux arunkumar.gupta 3.8.0-27-generic #40-Ubuntu SMP Tue Jul 9 00:19:35 UTC 2013 i686 i686 i686 GNU/Linux

Code

void
_log_message(int level, char *fmt, ...)
{
  int n;
  char *msg;
  va_list args;
  char time_string[TIME_LENGTH];
  char str[STRING_LENGTH];
  assert(level <= log_level);
  va_start(args, fmt);
  fill_time_string(time_string, TIME_LENGTH);
  n = snprintf(str, STRING_LENGTH, "%-9s %s [%s:%lu]: ", log_string[level], time_string, log_ident, (long int) getpid());
  msg = str + n;
  n  += vsnprintf(msg, STRING_LENGTH-n, fmt, args);
  if(n >= STRING_LENGTH) {
strcpy(str+STRING_LENGTH-6, " ...\n");
n = STRING_LENGTH-1;
  }


va_end(args);
}

Backtrace output

 ./a.out(handler+0x25)[0x401152]
 /usr/lib/libc.so.6(+0x35400)[0x7fb0e2358400]
 /usr/lib/libc.so.6(_IO_vfprintf+0x1cf0)[0x7fb0e236b1f0]
 /usr/lib/libc.so.6(vsnprintf+0x79)[0x7fb0e2395459]
 ./a.out(_log_message+0x1b7)[0x40169c]
 ./a.out(csc_open+0x71)[0x401894]
 ./a.out(open_log_file+0x43)[0x4018e3]
 ./a.out(main+0x5a)[0x4019c2]
 /usr/lib/libc.so.6(__libc_start_main+0xf5)[0x7fb0e2344b05]
./a.out[0x401069]

Please help me it's giving me error for Arch Linux machine( Which is 32 bit machine)and but not on Ubuntu 13.04(64 bit machine). Suggest me any alternative if possible?

Arun Gupta
  • 810
  • 2
  • 9
  • 26
  • 1
    1. What is `str1`? 2. You need to show the code which calls this function also. – Dark Falcon Apr 23 '14 at 18:08
  • Where is str1 defined? Where is n initialized? – Brad Budlong Apr 23 '14 at 18:08
  • 5
    `n` is not initialized. Also you should definitely turn gcc warnings on to avoid that kind of errors – z̫͋ Apr 23 '14 at 18:08
  • Sorry my fault let me correct the question :| again – Arun Gupta Apr 24 '14 at 04:56
  • You should check `n >= 0 && n < STRING_LENGTH` before doing the `vsnprintf`. Also, the problem could be that the args actually do contain junk (e.g. `%s` with null pointer) – M.M Apr 24 '14 at 05:12
  • `(long int)` should be `(unsigned long)`, `log_string[level]` might be an out-of-bounds access, and `time_string` and `log_ident` might not be null-terminated. (show more code!) – M.M Apr 24 '14 at 05:14
  • Also you never do anything with `str` after writing it, is that intentional? – M.M Apr 24 '14 at 05:16
  • @MattMcNabb yes it's intentional, will write another thing on that(str). – Arun Gupta Apr 24 '14 at 05:30
  • @MattMcNabb yes it's intentional, will write another thing on that(str). `Also, the problem could be that the args actually do contain junk (e.g. %s with null pointer)` this point makes sense but how it's not making error on other machine why. Is there any way to get rid of that? if it's creating error means if program getting junk `args` – Arun Gupta Apr 24 '14 at 05:41
  • No, you just have to be more careful about which arguments you pass in the first place. – M.M Apr 24 '14 at 06:40
  • May be for some times i don't send any arguments. `vsnprint` just like a `printf` it shouldn't pop any error. – Arun Gupta Apr 24 '14 at 10:35
  • Your code is incomplete; in particular, it seems to be missing a `main()` function and at least one `#include`. Please [edit] your code so it's a [mcve] of your problem (including any necessary inputs, but preferably not needing any), then we can try to reproduce and solve it. You should also read [ask]. – Toby Speight Feb 06 '19 at 15:13

1 Answers1

2

I got to this old question because something similar happened to me. After some head scratching I found the reason is that some invocations of my formatting method had something like the following:

int64_t num;
foo("%d", num);

In this case foo is a function which passes "%d" and num to vsnprintf as fmt and args. In a 64 bit architecture this worked fine, but for 32 bit this gave me SIGSEGV.

The fix was to change %d to %lld, or as suggested in How to print a int64_t type in C, change it to :

"%" PRId64

galsh83
  • 550
  • 3
  • 16
  • 1
    Any decent compiler should warn about that (even if not, then your Valgrind run should identify the problem). Perhaps you forgot to add the annotation that marks `foo` as using a format string? – Toby Speight Feb 06 '19 at 15:11
  • @TobySpeight tbh I didn't know about the possibility to annotate format string using functions. I learned about it now after seeing your comment. Thanks! – galsh83 Feb 06 '19 at 16:04
  • BTW, I realise that my comment looks like I'm knocking your answer; I didn't intend that, and I upvoted it as a good answer. – Toby Speight Feb 06 '19 at 16:07