Hello everyone,


For the following code, I can not set breakpoint in release mode, but the
same command in WinDbg works fine in debug mode. Anything wrong?

Here is my Windbg command and output in release mode and source codes. I
have tested in release mode breakpoint at foo does not take effect, but in
debug mode it takes effect.

0:000> bp foo
Bp expression 'foo' could not be resolved, adding deferred bp
0:000> bp main
0:000> bl
0 eu 0001 (0001) (foo)
1 e 00000001`40001000 0001 (0001) 0:**** Test64bitDebug!main

int foo (int a, int b)
{
return a+b;
}
int main()
{
int a1 = 100;
int b1 = a1 + 100;
a1 = foo (a1, b1);
return 0;
}


thanks in advance,
George

Re: can not set breakpoint in release mode by Alex

Alex
Sun Jul 13 05:56:15 CDT 2008

"George" wrote:
> For the following code, I can not set breakpoint in release
> mode, but the same command in WinDbg works fine in debug mode.
> Anything wrong?

Most likely the optimizer have inlined the `foo', so there is no
more such function.

Alex



Re: can not set breakpoint in release mode by Norbert

Norbert
Sun Jul 13 06:39:50 CDT 2008



Alex Blekhman schrieb:
> "George" wrote:
>> For the following code, I can not set breakpoint in release
>> mode, but the same command in WinDbg works fine in debug mode.
>> Anything wrong?
>
> Most likely the optimizer have inlined the `foo', so there is no
> more such function.

Even better, the optimizer has reduced the complete application to "return 0":

main:
00401000 xor eax,eax
00401002 ret

Even if you change the application to return a1, the resulting program changes to:

00401000 mov eax,12Ch
00401005 ret

Norbert

Re: can not set breakpoint in release mode by George

George
Sun Jul 13 07:03:06 CDT 2008

Thanks Alex,


How do you prove the optimized code "inline" foo?


regards,
George

Re: can not set breakpoint in release mode by George

George
Sun Jul 13 07:19:01 CDT 2008

Cool, Norbert!


I have also verified it. When I press command p (step next) after setting a
breakpoint in main, the following output is displayed,

0:000> p
Test64bitDebug!__tmainCRTStartup+0x11a:
00000001`400011c2 8905781e0000 mov dword ptr [Test64bitDebug!mainret
(00000001`40003040)],eax ds:00000001`40003040=00000000

My question is, whether this line indicates the end of main? And why?

(I have used k command to verify and here is the output and no main function
in the stack, so I prove main is returned, not sure whether it is the most
efficient and correct way.)

0:000> k
Child-SP RetAddr Call Site
00000000`0012ff50 00000000`77d5964c Test64bitDebug!__tmainCRTStartup+0x11a
00000000`0012ff80 00000000`00000000 kernel32!BaseProcessStart+0x29



regards,
George

Re: can not set breakpoint in release mode by Alex

Alex
Sun Jul 13 07:51:20 CDT 2008

"George" wrote:
> How do you prove the optimized code "inline" foo?

I don't have a proof. That's why I wrote "most likely" in my
original response. You have said that you cannot set a breakpoint,
so it was my first [educated] guess.

Alex



Re: can not set breakpoint in release mode by George

George
Mon Jul 14 00:39:00 CDT 2008

Thanks Alex,


Seems it is not inline. The assembly code for main function contains just a
return instruction. Any comments?


regards,
George

Re: can not set breakpoint in release mode by Ondrej

Ondrej
Mon Jul 14 05:29:02 CDT 2008

As already pointed out, this is a good optimizer seen in action. Default
options allow inlining any functions, which is what compiler did. After
inlining all expresions were constant, and as a result, no code to debug
was left after optimization except for returning the final constant value.

Ondrej
George napsal(a):
> Thanks Alex,
>
>
> Seems it is not inline. The assembly code for main function contains just a
> return instruction. Any comments?
>
>
> regards,
> George

Re: can not set breakpoint in release mode by George

George
Mon Jul 14 21:26:00 CDT 2008

Thanks Ondrej,


The function is not inlined, but completely optimized out. You can see in
the assembly code, it contains only 2 lines,

xor eax, eax
ret

Any comments?


regards,
George

Re: can not set breakpoint in release mode by Doug

Doug
Mon Jul 14 22:01:48 CDT 2008

On Mon, 14 Jul 2008 19:26:00 -0700, George
<George@discussions.microsoft.com> wrote:

>The function is not inlined, but completely optimized out. You can see in
>the assembly code, it contains only 2 lines,
>
>xor eax, eax
>ret
>
>Any comments?

I guess you're still talking about this:

int foo (int a, int b)
{
return a+b;
}
int main()
{
int a1 = 100;
int b1 = a1 + 100;
a1 = foo (a1, b1);
return 0;
}

VC's optimizer (as of version 5 or so) can certainly see inside the
function "foo" while it is compiling main (it's inside the same translation
unit, and even appears textually before main), so whether or not it's
inline or not doesn't matter. Your program contains no "observable
behavior", so the optimizer is well within its rights to optimize it as
you've described. What is "observable behavior"? IIRC, it consists of reads
and writes to volatile variables and calls to output functions in the
standard libraries. In practice, the compiler does not know what (Windows,
3rd party, your own) library functions do, and since it can't see inside
them, it must assume they produce observable behavior. You could try
various things to test this, such as passing the foo result to printf, or
use it to create a string for a MessageBox, etc. You should find the result
has been calculated at compile-time, and the correct constant is used in
place of the call.

--
Doug Harrison
Visual C++ MVP

Re: can not set breakpoint in release mode by George

George
Mon Jul 14 22:27:00 CDT 2008

Thanks Doug!


Great! I agree and understand all of your comments, except -- why "writes to
volatile variables" is observable behavior?


regards,
George

Re: can not set breakpoint in release mode by Doug

Doug
Mon Jul 14 22:49:53 CDT 2008

On Mon, 14 Jul 2008 20:27:00 -0700, George
<George@discussions.microsoft.com> wrote:

>Great! I agree and understand all of your comments, except -- why "writes to
>volatile variables" is observable behavior?

One reason is because the address of a volatile object might be mapped to
some hardware which causes some effect when written to. Another is to
ensure that seemingly purposeless (from the optimizer's perspective) writes
to volatile sig_atomic_t variables aren't discarded inside signal handlers.
There are probably others, but they are all similar in that (a) the writes
must occur, and (b) they must occur in the order given WRT other volatile
reads and writes. VC2005 takes it an unusual step further by giving
volatile reads/writes memory barrier properties; search Google and MSDN,
and you can find a lot of discussion on this if you're interested.

--
Doug Harrison
Visual C++ MVP

Re: can not set breakpoint in release mode by Igor

Igor
Mon Jul 14 23:04:37 CDT 2008

"George" <George@discussions.microsoft.com> wrote in message
news:B9E8ED99-5955-4E24-8BA4-1D22A0878259@microsoft.com
> Great! I agree and understand all of your comments, except -- why
> "writes to volatile variables" is observable behavior?

In many systems, especially embedded, volatile variables correspond to
hardware registers. Reading or writing such a variable directly affects
some physical hardware device attached to the computer. See also
http://en.wikipedia.org/wiki/MMIO
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: can not set breakpoint in release mode by George

George
Tue Jul 15 03:23:02 CDT 2008

Thanks Igor,


Question answered.


regards,
George