IDebugControl::OutputVaList and %I broken?

I’m unable to use the documented %I specifier to output ULONG64 parameters as 64 or 32 bit numbers.

Simple test code looks like this:

void Test(IDebugControl*pDC, PCSTR Fmt, …)
{
va_list val;
va_start(val, Fmt);
pDC->OutputVaList(DEBUG_OUTPUT_NORMAL, Fmt, val);
va_end(val);
}

IDebugControl*pDbgCtl = …;
Test(pDbgCtl, “Value=%I\n”, 0x1122334455667788ull);

In a 64-bit extension it prints “Field formatting string too long” and “Unknown format character” in 32-bit.

I’m specifically looking for the supposed ability to print fewer leading zeros when the 64-bit value is <= 0xffffffff. I don’t want to convert to a string on my own first, I just want to replace %p in a few places…

not sure if %i is documented i use %I64x normally and it appears to work

Out(“Rva For Inaddress %I64x is %I64X\n” ,inaddr ,(inaddr - Modbase));

On 11/25/16, xxxxx@techie.com wrote:
> I’m unable to use the documented %I specifier to output ULONG64 parameters
> as 64 or 32 bit numbers.
>
> Simple test code looks like this:
>
> void Test(IDebugControlpDC, PCSTR Fmt, …)
> {
> va_list val;
> va_start(val, Fmt);
> pDC->OutputVaList(DEBUG_OUTPUT_NORMAL, Fmt, val);
> va_end(val);
> }
>
> IDebugControl
pDbgCtl = …;
> Test(pDbgCtl, “Value=%I\n”, 0x1122334455667788ull);
>
> In a 64-bit extension it prints “Field formatting string too long” and
> “Unknown format character” in 32-bit.
>
> I’m specifically looking for the supposed ability to print fewer leading
> zeros when the 64-bit value is <= 0xffffffff. I don’t want to convert to a
> string on my own first, I just want to replace %p in a few places…
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>

On Nov 24, 2016, at 2:37 PM, xxxxx@techie.com wrote:

I’m unable to use the documented %I specifier to output ULONG64 parameters as 64 or 32 bit
numbers.

The capital-I thing in a Microsoft printf string is not a specifier. It is a modifier. You need to follow it with the actual specifier, as in “%Id” or “%Ix”.

However, %Id is the wrong thing to use for ULONG64. A ULONG64 is always 64 bits. “%Id” tells printf “you should expect a 32-bit thing in a 32-bit build”. That’s not what you are providing.

You should use “%I64d” or “%I64x” in this case.
?
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

*sigh*

I know %I is normally a Microsoft specific modifier but OutputVaList is not in any way a normal printf function (%p is always ULONG64 and it supports strange things like %msa, %y etc.).

If you look at the documentation for OutputVaList which is currently located @ https://msdn.microsoft.com/en-us/library/windows/hardware/ff553280(v=vs.85).aspx you will see a table of specifiers including “%I” and it specifically says the argument is always ULONG64 and “If this is greater than 0xFFFFFFFF, it is printed as a 64-bit value; otherwise, it is printed as a 32-bit value.” which is exactly what I want, I just can’t get it to work.

So my question is, is the documentation wrong or is the implementation broken?

I can verify that this is a bug in?the debugger. We’ve filed it but I don’t have an ETA on when we’ll have a?fix available.

Thank you for confirming this.

Has it always been broken or does it work in some versions?