inline functions

S

Sergio Durigan Junior

On 11/29/2012 10:24 AM, Malcolm McLean wrote:
...
But I usually find diagnostic printfs() easier to work with than debuggers.

[...] We're now using exclusively
gcc, and I have only gdb to debug with, and even when I compile with
-O0, the behavior of the code as displayed by gdb quite frequently
deviates significantly from what I wrote. I can't be sure whether this
is due to the compiler or the debugger, or both.

This really shouldn't happen. Have you filed any bugs for GDB? If not,
I'd suggest you do so. What is the version of GCC and GDB that you're
using? It is very hard to say, but it seems GCC is generating wrong
debug information and GDB is getting lost.

Anyway, I was one of the 'printf' guys before myself, but when I really
learned how to use a debugger in a decent way, I must confess that it's
been ages since I don't do printf-debugging :). But of course, I guess
this is more a matter of taste than anything else.
 
I

Ian Collins

James said:
On 11/29/2012 10:24 AM, Malcolm McLean wrote:
....

In my experience, that depends upon the debugger, the compiler, and the
type of problem being debugged. We used to use the Irix MIPS-Pro C
compiler, and I used dbx to debug problems when necessary; I only rarely
felt the need to use debugging printf()s. We're now using exclusively
gcc, and I have only gdb to debug with, and even when I compile with
-O0, the behavior of the code as displayed by gdb quite frequently
deviates significantly from what I wrote. I can't be sure whether this
is due to the compiler or the debugger, or both.
As a result, I've often found it necessary to use debugging printf()s to
extract information about what's going on that's actually consistent
with the way I wrote the code.

If you are working on OS X, Solaris or FeeeBSD, you can insert DTrace
probes in your code to extract information about what's going on and
leave them there to help you analyse performance in production. Very handy!
 
L

Les Cargill

Sergio said:
On 11/29/2012 10:24 AM, Malcolm McLean wrote:
...
But I usually find diagnostic printfs() easier to work with than debuggers.

[...] We're now using exclusively
gcc, and I have only gdb to debug with, and even when I compile with
-O0, the behavior of the code as displayed by gdb quite frequently
deviates significantly from what I wrote. I can't be sure whether this
is due to the compiler or the debugger, or both.

This really shouldn't happen. Have you filed any bugs for GDB? If not,
I'd suggest you do so. What is the version of GCC and GDB that you're
using? It is very hard to say, but it seems GCC is generating wrong
debug information and GDB is getting lost.

Anyway, I was one of the 'printf' guys before myself, but when I really
learned how to use a debugger in a decent way, I must confess that it's
been ages since I don't do printf-debugging :). But of course, I guess
this is more a matter of taste than anything else.


it's a matter of having a competent debugger to work with. And a
debugger isn't likely to help much with "emergent" defects - stuff
that fails only in the final hardware in a real configuration.
 
S

Sergio Durigan Junior

If you are working on OS X, Solaris or FeeeBSD, you can insert DTrace
probes in your code to extract information about what's going on and
leave them there to help you analyse performance in production. Very
handy!

And if you're working on GNU/Linux, you can also insert SDT probes in
your code to achieve the same effect. These probes are also known as
SystemTap userspace probes, and all you need to to is to install
`systemtap-sdt-devel' (if you're on Fedora), and #include <sys/sdt.h> in
your code.

Recently, GDB became aware of such probes as well, so you can access
them inside the debugger. I made a series of blog posts to ilustrate
the process of including the probes in your program and accessing them
inside GDB:

http://blog.sergiodj.net/post/2012-03-29-gdb-and-systemtap-probes-part-1/

http://blog.sergiodj.net/post/2012-10-27-gdb-and-systemtap-probes-part-2/

http://blog.sergiodj.net/post/2012-11-02-gdb-and-systemtap-probes-part-3/

Hope that helps :).
 
S

Sergio Durigan Junior

it's a matter of having a competent debugger to work with. And a
debugger isn't likely to help much with "emergent" defects - stuff
that fails only in the final hardware in a real configuration.

Sorry, but I fail to see your point. I understand that debugging
failures in a production environment sometimes is hard not just because
of the problem itself, but because you just can't stop your business.
Is that what you mean? If it is, I agree, but then I believe you can
try other solutions (like inserting probes in your code, mentioned in
another reply to this sub-thread). However, eventually you will have to
debug your application in a test environment to (at least try to)
replicate the problem you saw on production. In this case, a debugger
helps a lot.
 
L

Les Cargill

Sergio said:
Sorry, but I fail to see your point. I understand that debugging
failures in a production environment sometimes is hard not just because
of the problem itself, but because you just can't stop your business.
Is that what you mean?


No. These are the sort of bugs you find only in a fully loaded system.
They're generally requirement-based defects, not coding errors. I found
that I didn't know well enough how to test to requirements, so that
was the next educational step.
If it is, I agree, but then I believe you can
try other solutions (like inserting probes in your code, mentioned in
another reply to this sub-thread).

yes - that's what I'd generally do ( lots of logging ).
However, eventually you will have to
debug your application in a test environment to (at least try to)
replicate the problem you saw on production. In this case, a debugger
helps a lot.

Right - although I found test harnesses to have more lasting
value, because you can add to them to make a living
regression suite.
 
J

Jorgen Grahn

To get good code, it is
important to give the compiler freedom to generate it's best code - that
means [...] and either turning off debug information generation,
or at least picking the most expressive possible debug format (so that
the compiler does not restrict code generation to suit debugger
capabilities).

Do any compilers still work that way? Which ones? I remember fighting
that idea fifteen years ago. People kept saying

"We can't enable debug symbols, because that would disable
optimization."

or the dreaded

"We'll enable optimization later, when we ship the code. We can't
do it now, because it would disable debug information."

even though our particular compiler's documentation clearly showed
that these were unrelated settings.

Come to think of it, the fight is still ongoing. Only a month ago I
enabled optimization for a piece of performance-critical code.

It's not just a matter of ancient compilers that can't combine debugging
with optimization.

True, there are other considerations. But the claim was that compilers
can't generate optimized code if debug info is enabled, and that was
what I was questioning.

/Jorgen
 
S

Sergio Durigan Junior

or change to clang, that produces quite readable, annotated assembler
with the -S option, for which it is much easier to keep track of the
source lines, much better than gcc

Don't want to cause any flamewars here (nor to hijack the thread), but
can you provide an example? You can use the various -d* (I'm thinking
about -dp here, actually) options on GCC to make it annotate the
assembler. Don't know how clang annotates it, I don't have it installed
here.

Thanks,
 
J

Jens Gustedt

Am 05.12.2012 06:19, schrieb Sergio Durigan Junior:
Don't want to cause any flamewars here (nor to hijack the thread),

me neither
but can you provide an example?
You can use the various -d* (I'm thinking
about -dp here, actually) options on GCC to make it annotate the
assembler.

-dp provides a very low level annotation of every assembler statement,
usually not what *I* need to understand the assembler something like

uComp:
..LFB683:
.cfi_startproc
testq %rdx, %rdx # 10 *cmpdi_ccno_1/1 [length = 3]
je .L586 # 11 *jcc_1 [length = 2]
movq (%rdx), %rcx # 13 *movdi_internal_rex64/2 [length = 3]
xorl %edx, %edx # 88 *movdi_xor [length = 2]
movq (%rdi), %rax # 14 *movdi_internal_rex64/2 [length = 3]
divq %rcx # 76 *udivmoddi4_noext [length = 3]
movq (%rsi), %rax # 17 *movdi_internal_rex64/2 [length = 3]
movq %rdx, %rdi # 71 *movdi_internal_rex64/2 [length = 3]
xorl %edx, %edx # 89 *movdi_xor [length = 2]
divq %rcx # 78 *udivmoddi4_noext [length = 3]
xorl %ecx, %ecx # 90 *movsi_xor [length = 2]
cmpq %rdx, %rdi # 91 *cmpdi_1/1 [length = 3]
movl $-1, %eax # 7 *movsi_internal/1 [length = 5]
seta %cl # 92 *setcc_qi_slp [length = 3]
cmovae %ecx, %eax # 63 *movsicc_noc/1 [length = 3]
ret # 82 return_internal [length = 1]
.p2align 4,,10
.p2align 3
..L586:
movq (%rsi), %rcx # 72 *movdi_internal_rex64/2 [length = 3]
xorl %edx, %edx # 85 *movsi_xor [length = 2]
movl $-1, %eax # 6 *movsi_internal/1 [length = 5]
cmpq %rcx, (%rdi) # 86 *cmpdi_1/1 [length = 3]
seta %dl # 87 *setcc_qi_slp [length = 3]
cmovae %edx, %eax # 67 *movsicc_noc/1 [length = 3]
ret # 84 return_internal [length = 1]
.cfi_endproc
..LFE683:
.size uComp, .-uComp

Don't know how clang annotates it, I don't have it installed
here.

Clang (with just -S) annotates the same code more lightly but with
higher level annotations corresponding to the structure of the source,
here in particular the if-then-else constructs that generated the
branching.

uComp: # @uComp
.cfi_startproc
# BB#0: # %entry
testq %rdx, %rdx
je .LBB9_3
# BB#1: # %if.then
movq (%rsi), %rax
movq (%rdx), %rsi
xorl %edx, %edx
divq %rsi
movq %rdx, %rcx
movq (%rdi), %rax
xorl %edx, %edx
divq %rsi
movl $-1, %eax
cmpq %rcx, %rdx
jb .LBB9_5
# BB#2: # %cond.false
cmpq %rcx, %rdx
jmp .LBB9_4
..LBB9_3: # %if.else
movq (%rsi), %rcx
movq (%rdi), %rdx
movl $-1, %eax
cmpq %rcx, %rdx
jb .LBB9_5
..LBB9_4: # %cond.false.i
seta %al
movzbl %al, %eax
..LBB9_5: # %return
ret
..Ltmp115:
.size uComp, .Ltmp115-uComp
.cfi_endproc


Jens
 
N

Noob

Jorgen said:
True, there are other considerations. But the claim was that compilers
can't generate optimized code if debug info is enabled, and that was
what I was questioning.

On a related note, gcc now supports a "-Og" optimization level.

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-Og-734
Optimize debugging experience. -Og enables optimizations that do not
interfere with debugging. It should be the optimization level of
choice for the standard edit-compile-debug cycle, offering a
reasonable level of optimization while maintaining fast compilation
and a good debugging experience.

Regards.
 
S

Sergio Durigan Junior

-dp provides a very low level annotation of every assembler statement,
usually not what *I* need to understand the assembler something like

Yeah, it is very low level indeed.
Clang (with just -S) annotates the same code more lightly but with
higher level annotations corresponding to the structure of the source,
here in particular the if-then-else constructs that generated the
branching.

Ok, I see it.

You can achieve the same effect with GCC by compiling the program with
-g (debug information) and using `objdump -S' on the binary. It will
give you an output like:

00000000004004a9 <main>:

int
main ()
{
4004a9: 55 push %rbp
4004aa: 48 89 e5 mov %rsp,%rbp
4004ad: 48 83 ec 10 sub $0x10,%rsp
int a;

a = 10;
4004b1: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)

if (a < 20)
4004b8: 83 7d fc 13 cmpl $0x13,-0x4(%rbp)
4004bc: 7f 0c jg 4004ca <main+0x21>
foo ();
4004be: e8 d9 ff ff ff callq 40049c <foo>
else
return 0;

return 0;
4004c3: b8 00 00 00 00 mov $0x0,%eax
4004c8: eb 05 jmp 4004cf <main+0x26>
a = 10;

if (a < 20)
foo ();
else
return 0;
4004ca: b8 00 00 00 00 mov $0x0,%eax

return 0;
}
4004cf: c9 leaveq
4004d0: c3 retq
4004d1: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4004d8: 00 00 00
4004db: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

Anyway, different ways to do it with different tools.

Regards,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

inline functions not inlined 9
inline vs. function pointers 36
inline functions 2
inline + va_list 4
Inline functions and linkage 5
about inline functions 14
Inline Functions? 3
static inline functions and gcc 21

Members online

Forum statistics

Threads
474,077
Messages
2,570,567
Members
47,203
Latest member
EmmaSwank1

Latest Threads

Top