Wireshark-dev: Re: [Wireshark-dev] Sprintf weirdness
From: Eloy Paris <peloy@xxxxxxxxxx>
Date: Wed, 02 Jun 2010 00:31:27 -0400
Hi Ian,

On 06/02/2010 12:01 AM, Ian Schorr wrote:

Hello list,

This isn't exactly a Wireshark-specific question, but it's coming up
while I'm working on a dissector, and I'm sure someone here will know
the answer, so...  =)

I'm trying to use sprintf() to append to an existing string with some
formatted text.  Obviously there's several ways to do this, but
sprintf() seemed to be most efficient for the way I'm doing things.  I
end up appending this string to the Info Column later, but that seems
irrelevant.

For example, I have 4 variables:
- string mystring, with value "LOCK"
- guint32 last_fh_hash, with value "2056735708"
- guint64 file_offset, with value 0
- guint64 lock_length, with value 10

The weird thing is that when I do this:

sprintf (mystring, "%s FH: 0x%08x Offset: %lu Length: %lu",
mystring,last_fh_hash,file_offset,lock_length);

...then "mystring" becomes "LOCK FH: 0x7a974bdc Offset: 0 Length: 0".
Length is WRONG.  It is wrong in a very consistent way.

But if I do this:

sprintf (mystring, "%s FH: 0x%08x", mystring,last_fh_hash);
sprintf (mystring, "%s Offset: %u", mystring,file_offset);
sprintf (mystring, "%s Length: %u", mystring,lock_length);

Then the resulting value of mystring is correct.  "LOCK FH: 0x7a974bdc
Offset: 0 Length: 10".  In fact, if I flip the positions of
"file_offset" and "lock_length" then things are fine, regardless of
their values.

It's difficult to reproduce or debug.  I have a number of similar
statements scattered throughout code and each has varying degrees of
strangeness.  Some work properly.  In some cases the values are
actually flipped (one variable printed one place, the other in
another).  In some cases the values are actually empty.  I can't
imagine it has anything to do with the way the string was declared or
memory allocated in the first place, it looks like sprintf() is simply
writing out the wrong values to memory for some reason.

Anybody have any thoughts on why that might be?  I'm assuming I've
done something silly, though having a tough time guessing where.

I haven't tested yet to see if this is something specific to the dev
platform I'm using.  At the moment that's Windows.

Just a suggestion: why don't you try to use the PRIxxx macros defined in stdint.h? I believe they're pretty portable since they are specified by ISO C99.

To use them in the specific example you used, you'd do something like:

#include <stdint.h>

...

sprintf (mystring, "%s FH: 0x%08" PRIx32 " Offset: %" PRIu64 " Length: %" PRIu64, mystring,last_fh_hash,file_offset,lock_length);

I think these macros are the best portable way of handling these variables that are represented by different basic integer types depending on the platform. Worth giving it a try...

Cheers,

Eloy Paris.-
netexpect.org