I just read about the GCC function attribute artificial
but did not quite get the description. Can you give me some examples where it is useful?
The other answer isn't wrong, but perhaps I can explain it a bit better.
Imagine this function in foo.c
, with line numbers:
10: static inline int foo(struct q *x)
11: {
12: return bar(x + 1);
13: }
This is called twice from another function:
20: void baz(void)
21: {
22: x = foo(qa);
23: x = foo(qb);
24: }
Unfortunately, bar()
crashes. Here's the backtrace: #0 0x00000000004b1a2a in bar (x=0x8) at foo.c:5
#1 0x0000000000416ee0 in baz () at foo.c:12
#2 0x0000000000413fab in main () at foo.c:30
Since foo
is inlined, it's not part of the backtrace, but wait, foo.c:12
is in foo
, and below it is just the line in main
. There's nothing to tell us what line in baz
caused the crash.
If we mark foo as artificial, we'd instead get this backtrace: #0 0x00000000004b1a2a in bar (x=0x8) at foo.c:5
#1 0x0000000000416ee0 in baz () at foo.c:22
#2 0x0000000000413fab in main () at foo.c:30
It no longer points to foo
. Instead it shows us where foo
was called from foo.c:22
. Suddendly it's easy to tell that qa
is the problematic variable.
From the gcc docs,
This attribute is useful for small inline wrappers that if possible should appear during debugging as a unit. Depending on the debug info format it either means marking the function as artificial or using the caller location for all instructions within the inlined body.
In the Inline is as fast as a Macro, there is a special note at the end on extern inline
functions. The idea is that if you have a header with the extern inline
, you can use the artificial attribute and the debug information will use the location where the inline
is used. Ie, where the extern inline
is called and inlined.
As in the description, artificial is only ever used with inlining and it controls the way a debugger will treat this code. It doesn't have an effect on generated code or anything else.
According to Ian Lance Taylor, one of the GCC devs, at __gnu_inline__
and __artificial__
:
I admit the docs for the artificial attribute are not very good. On a function, it basically means that if the function is inlined, the debugger will not step through the inlined instructions.
Can you give me some examples where it is useful?
I can provide at least one additional one: stepping code with inline assembly one-liners from C. Often times, you want the next C statement, not the next assembly statement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With