This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] convert a host address to a string


gdb-patches-owner@sourceware.org wrote on 08.01.2009 11:19:11:

> > Probably not, but there's a problem with %p.  While it is specified by
> > C90 and almost certainly implemented in the C library of all systems
> > we care about, it is implemented how exactly the pointer will be
> > printed.  On OpenBSD and Linux it is something like 0xNNNNNNNN, but
> > Solaris generates NNNNNNNN (without the initial 0x).  That's
> > undesirable I think.
> 
> I agree.
> 
> > An option would be to use the strategy used by phex_nz() to print host
> > addresses.  Or we could use PRINTF_HAS_LONG_LONG, and always use %llx
> > if it's available.
> 
> Unfortunately, I don't know how this could be made to work.
> The problem is that GCC insists that the integer type that we
> use to cast the host address to must have the same size.
> At one point, hoping that GCC would kill the wrong branch,
> I even tried:
> 
>   if (sizeof (void *) == sizeof (long))
>     printf ("0x%lx", (long) address);
>   else
>     printf ("0x%llx", (long long) address);
> 
> But this didn't work, because GCC complained about the cast
> in the "if" branch.
> 
> Actually, it's only after writing the entire email that I realized
> that we have another option. See option (3) below.
> 
> > I'd really like to avoid introducing another macro dealing with
> > type-size issues if possible.  I especially dislike HOST_IS_LLP64
> > since I fear its existence encourages people to write unportable code.
> 
> I can see several solutions:
> 
>   1. Use %p. To overcome the problem with 0x, we could use
>      two alternatives:
> 
>        a. Import printf from gnulib. I looked at this a while ago,
>           for some other issue, and I immediately stopped, as it
>           looked like it might be a lot of work to do so (printf
>           doesn't come alone, there's a bunch of other routines
>           that printf uses which we probably want).
> 
>        b. Strip the leading "0x" if %p already provides it. In other
>           words:
> 
>             fprintf (buf, "0x%p", address);
>             if (buf[2] == '0' && buf[3] == 'x')
>               buf = buf + 2;
>             return buf;
> 
>           There is no memory management issue in this case, because
>           the buffer we return is more or less static. It's part
>           of a bunch of buffers we cycle through each time we call
>           this routine.  The caller never frees the memory we return.
> 
>   2. Avoid the HOST_IS_LLP64 macro, but still do something similar
>      inside host_address_to_string. Something like:
> 
>        #if defined(WIN64_)
>            fprintf (buf, "0x%llx", (unsigned long long) address);
>        #else
>            fprintf (buf, "0x%lx", (unsigned long) address);
>        #endif
> 
>      This eliminates the likeliness of re-using the HOST_IS_LLP64
>      macro to write non-portable code.
> 
>   3. Work through uintptr_t.
> 
>        #ifdef PRINTF_HAS_LONG_LONG
>          fprintf (buf, "0x%llx", (unsigned long long) (uintptr_t) 
address);
>        #else
>          fprintf (buf, "0x%lx", (unsigned long) (uintptr_t) address);
>        #endif
> 
> For completeness' sake, I also investigate the use of the PRIxPTR
> macro, but we still have the problem of casting the address to
> the right integer type: If PRIxPTR resolves to "lx", then we should
> cast to "long", otherwise, we should cas to "long long".
> 
> I kinda like option 1b as being simple and avoiding the need to
> cast the address to an integer.  Option (3) is my next favorite,
> but I don't like the fact that we end up doing an unnecessary
> integer promotion on the 32bit targets. Perhaps we could avoid that
> using an extra "if (sizeof (void *) != sizeof (long))" but then
> the code becomes increasingly complex. My next favorite would
> probably be option 2 because I'm lazy, but it's really not elegant.
> Option 1 looks like a fair amount of work, but would give us access
> to a predicatable printf.
> 
> Thoughts?
> 
> -- 
> Joel
> 

Why not simply use stdint.h (gstdint.h) for this?

Cheers,
Kai

|  (\_/)  This is Bunny. Copy and paste Bunny
| (='.'=) into your signature to help him gain
| (")_(") world domination.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]