Gnu C++ How to Check When -Std=C++0X Is in Effect

Any good C++0x overviews?

The best two I know of are the Wikipedia page and Stroustrup's FAQ.

I really wouldn't recommend reading the standard until you know what you're looking for. Besides being significantly larger than the C++03 standard, the organization and clarity has gotten somewhat worse in parts.

If you're only going to do one lecture on "advanced C++", you might focus on C++0x features which were adopted from other common sources, such as boost::smart_ptr and std::tr1::unordered_map. Such things are ahead of the curve on adoption.

Knowing the size of a C function in the compiled objectfile

I have found that the output of objdump -t xxx will give definitive function size/length values for program and object files (.o).

For example: (From one of my projects)

objdump -t emma | grep " F .text"

0000000000401674 l F .text 0000000000000376 parse_program_header
00000000004027ce l F .text 0000000000000157 create_segment
00000000004019ea l F .text 000000000000050c parse_section_header
0000000000402660 l F .text 000000000000016e create_section
0000000000401ef6 l F .text 000000000000000a parse_symbol_section
000000000040252c l F .text 0000000000000134 create_symbol
00000000004032e0 g F .text 0000000000000002 __libc_csu_fini
0000000000402240 g F .text 000000000000002e emma_segment_count
00000000004022f1 g F .text 0000000000000055 emma_get_symbol
00000000004021bd g F .text 000000000000002e emma_section_count
0000000000402346 g F .text 00000000000001e6 emma_close
0000000000401f00 g F .text 000000000000002f emma_init
0000000000403270 g F .text 0000000000000065 __libc_csu_init
0000000000400c20 g F .text 0000000000000060 estr
00000000004022c3 g F .text 000000000000002e emma_symbol_count
0000000000400b10 g F .text 0000000000000000 _start
0000000000402925 g F .text 000000000000074f main
0000000000401f2f g F .text 000000000000028e emma_open

I've pruned the list a bit, it was lengthy. You can see that the 5th column (the second wide column with lots of zeros....) gives a length value for every function. main is 0x74f bytes long, emma_close is 0x1e6, parse_symbol_section is a paltry 0x0a bytes... 10 bytes! (wait... is that a stub?)

Additionally, I grep'd for just the 'F'unctions in the .text section, thus limiting the list further. The -t option to objdump shows only the symbol tables, so it omits quite a bit of other information not particularly useful towards function length gathering.

I suppose you could use it like this:

objdump -t MYPROG | grep "MYFUNCTION$" | awk '{print "0x" $(NF-1)}' | xargs -I{} -- python -c 'print {}'

An example:

00000000004019ea l F .text 000000000000050c parse_section_header

$ objdump -t emma | grep "parse_section_header$" | awk '{print "0x" $(NF-1)}' | xargs -I{} -- python -c 'print {}'
1292

Checks out, since 0x50c == 1292.

I used $(NF-1) to grab the column in awk since the second field can vary in content and spaces depending on the identifiers relevant to the symbol involved. Also, note the trailing $ in the grep, causing main to find the main function, not the entry with main.c as its name.

The xargs -I{} -- python -c 'print {}' bit is to convert the value from hex to decimal. If anyone can think of an easier way, please chime in. (You can see where awk is sneaking the 0x prefix in there).

Ah, I just remembered that I have an alias for objdump which presets the demangle option for objdump. It'll make things easier to match if you add --demangle to the objdump invocation. (I also use --wide, much easier to read, but doesn't affect this particular output).

This works on any ELF object, library, program, object file, as long as it's NOT stripped. (I tested with and without debugging symbols too)

Hope this helps.

(I looked, parse_symbol_section IS a stub.)

Are all functions in C/C++ assumed to return?

Is the compiler free to assume that a function will always return?

It is not legal in C or C++ for a compiler to optimize on that basis, unless it somehow specifically knows that ereport returns (for example by inlining it and inspecting the code).

ereport depends on at least one #define and on the values passed in, so I can't be sure, but it certainly looks to be designed to conditionally not return (and it calls an extern function errstart that, as far as the compiler knows, may or may not return). So if the compiler really is assuming that it always returns then either the compiler is wrong, or the implementation of ereport is wrong, or I've completely misunderstood it.

The paper says,

However, the programmer failed to inform the compiler that the call to
ereport(ERROR, ::: ) does not return.

I don't believe that the programmer has any such obligation, unless perhaps there's some non-standard extension in effect when compiling this particular code, that enables an optimization that's documented to break valid code under certain conditions.

Unfortunately it is rather difficult to prove the code transformation is incorrect by citing the standard, since I can't quote anything to show that there isn't, tucked away somewhere in pages 700-900, a little clause that says "oh, by the way, all functions must return". I haven't actually read every line of the standard, but such a clause would be absurd: functions need to be allowed to call abort() or exit() or longjmp(). In C++ they can also throw exceptions. And they need to be allowed to do this conditionally -- the attribute noreturn means that the function never returns, not that it might not return, and its absence proves nothing about whether the function returns or not. My experience of both standards is that they aren't (that) absurd.

Optimizations are not allowed to break valid programs, they're constrained by the "as-if" rule that observable behaviour is preserved. If ereport doesn't return then the "optimization" changes the observable behaviour of the program (from doing whatever ereport does instead of returning, to having undefined behaviour due to the division by zero). Hence it is forbidden.

There's more information on this particular issue here:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=616180

It mentions a GCC bug report http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29968 that was (rightly IMO) rejected, but if ereport doesn't return then the PostGreSQL issue is not the same as that rejected GCC bug report.

In the debian bug description is the following:

The gcc guys are full of it. The issue that is relevant here is the C
standard's definition of sequence points, and in particular the
requirement that visible side effects of a later statement cannot
happen before the execution of an earlier function call. The last
time I pestered them about this, I got some lame claim that a SIGFPE
wasn't a side effect within the definitions of the spec. At that
point useful discussion stopped, because it's impossible to negotiate
with someone who's willing to claim that.

In point of fact, if a later statement has UB then it is explicitly stated in the standard that the whole program has UB. Ben has the citation in his answer. It is not the case (as this person seems to think) that all visible side effects must occur up to the last sequence point before the UB. UB permits inventing a time machine (and more prosaically, it permits out of order execution that assumes everything executed has defined behaviour). The gcc guys are not full of it if that's all they say.

A SIGFPE would be a visible side effect if the compiler chooses to guarantee and document (as an extension to the standard) that it occurs, but if it's just the result of UB then it is not. Compare for example the -fwrapv option to GCC, which changes integer overflow from UB (what the standard says) to wrap-around (which the compiler guarantees, only if you specify the option). On MIPS, gcc has an option -mcheck-zero-division, which looks like it does define behaviour on division by zero, but I've never used it.

It's possible that the authors of the paper noticed the wrongness of that complaint against GCC, and the thought that one of the PostGreSQL authors was wrong in this way influenced them when they put the snigger quotes into:

We found seven similar issues in PostgreSQL, which were noted as “GCC
bugs” in source code comments

But a function not returning is very different from a function returning after some side effects. If it doesn't return, the statement that would have UB is not executed within the definition of the C (or C++) abstract machine in the standard. Unreached statements aren't executed: I hope this isn't contentious. So if the "gcc guys" were to claim that UB from unreached statements renders the whole program undefined, then they'd be full of it. I don't know that they have claimed that, and at the end of the Debian report there's a suggestion that the issue might have gone away by GCC 4.4. If so then perhaps PostGreSQL indeed had encountered an eventually-acknowledged bug, not (as the author of the paper you link to thinks) a valid optimization or (as the person who says the gcc guys are full of it thinks) a misinterpretation of the standard by GCC's authors.

How to get a stack trace for C++ using gcc with line number information?

Not too long ago I answered a similar question. You should take a look at the source code available on method #4, which also prints line numbers and filenames.

  • Method #4:

A small improvement I've done on method #3 to print line numbers. This could be copied to work on method #2 also.

Basically, it uses addr2line to convert addresses into file names and line numbers.

The source code below prints line numbers for all local functions. If a function from another library is called, you might see a couple of ??:0 instead of file names.

#include <stdio.h>
#include <signal.h>
#include <stdio.h>
#include <signal.h>
#include <execinfo.h>

void bt_sighandler(int sig, struct sigcontext ctx) {

void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;

if (sig == SIGSEGV)
printf("Got signal %d, faulty address is %p, "
"from %p\n", sig, ctx.cr2, ctx.eip);
else
printf("Got signal %d\n", sig);

trace_size = backtrace(trace, 16);
/* overwrite sigaction with caller's address */
trace[1] = (void *)ctx.eip;
messages = backtrace_symbols(trace, trace_size);
/* skip first stack frame (points here) */
printf("[bt] Execution path:\n");
for (i=1; i<trace_size; ++i)
{
printf("[bt] #%d %s\n", i, messages[i]);

/* find first occurence of '(' or ' ' in message[i] and assume
* everything before that is the file name. (Don't go beyond 0 though
* (string terminator)*/
size_t p = 0;
while(messages[i][p] != '(' && messages[i][p] != ' '
&& messages[i][p] != 0)
++p;

char syscom[256];
sprintf(syscom,"addr2line %p -e %.*s", trace[i], p, messages[i]);
//last parameter is the file name of the symbol
system(syscom);
}

exit(0);
}

int func_a(int a, char b) {

char *p = (char *)0xdeadbeef;

a = a + b;
*p = 10; /* CRASH here!! */

return 2*a;
}

int func_b() {

int res, a = 5;

res = 5 + func_a(a, 't');

return res;
}

int main() {

/* Install our signal handler */
struct sigaction sa;

sa.sa_handler = (void *)bt_sighandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;

sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
/* ... add any other signal here */

/* Do something */
printf("%d\n", func_b());
}

This code should be compiled as: gcc sighandler.c -o sighandler -rdynamic

The program outputs:

Got signal 11, faulty address is 0xdeadbeef, from 0x8048975
[bt] Execution path:
[bt] #1 ./sighandler(func_a+0x1d) [0x8048975]
/home/karl/workspace/stacktrace/sighandler.c:44
[bt] #2 ./sighandler(func_b+0x20) [0x804899f]
/home/karl/workspace/stacktrace/sighandler.c:54
[bt] #3 ./sighandler(main+0x6c) [0x8048a16]
/home/karl/workspace/stacktrace/sighandler.c:74
[bt] #4 /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0x3fdbd6]
??:0
[bt] #5 ./sighandler() [0x8048781]
??:0

GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file

You have to weaken and globalize the symbol using objcopy.

-W symbolname
--weaken-symbol=symbolname
Make symbol symbolname weak. This option may be given more than once.
--globalize-symbol=symbolname
Give symbol symbolname global scoping so that it is visible outside of the file in which it is defined. This option may be given more than once.

This worked for me

bar.c:

#include <stdio.h>
int foo(){
printf("Wrap-FU\n");
}

foo.c:

#include <stdio.h>

void foo(){
printf("foo\n");
}

int main(){
printf("main\n");
foo();
}

Compile it

$ gcc -c foo.c bar.c 

Weaken the foo symbol and make it global, so it's available for linker again.

$ objcopy foo.o --globalize-symbol=foo --weaken-symbol=foo foo2.o

Now you can link your new obj with the wrap from bar.c

$ gcc -o nowrap foo.o #for reference
$ gcc -o wrapme foo2.o bar.o

Test

$ ./nowrap 
main
foo

And the wrapped one:

$ ./wrapme 
main
Wrap-FU

Using __thread in c++0x

It's thread_local, not __thread. It's used to define variables which has storage duration of the thread.

thread_local is a new storage duration specifier added in C++0x. There are other storage duration : static, automatic and dynamic.

From this link:

thread local storage duration (C++11 feature). The variable is allocated when the thread begins and deallocated when the thread ends. Each thread has its own instance of the variable. Only variables declared thread_local have this storage duration.


I think the introduction of this keyword was made possible by introducing a standardized memory model in C++0x:

  • C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?


Related Topics



Leave a reply



Submit