What Every C Programmer Should Know About Undefined Behavior #1/3
1–10 of 19 posts
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#2It was roughly this
read-from-p;
if(p != NULL) write-to-p;
since read-from-p is undefined if p is null, gcc could (and did) legally optimize out the NULL check, so you could end up writing to NULL.
[edit] I noticed that this case of bug is actually mentioned in the regehr article that is linked.
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#3I still remember one of my favorite linux bugs was due to the NULL behavior. It was roughly this read-from-p; if(p != NULL) write-to-p; since read-from-p is undefined if p is null, gcc could (and did) legally optimize out the NULL check, so you could end up writing to NULL. [edit] I noticed that this case of bug is actually mentioned in the regehr article that is linked.
#define TRACE_FOO(foo_ptr) TRACE_INT((foo_ptr)->x)
...
TRACE_ENTER(TRACE_INT(x) TRACE_FOO(foo_ptr));
if(!foo_ptr) return NULL;
use foo-ptr
The NULL check was optimized out. The dereference of foo_ptr was hidden behind TRACE_FOO, which made it even harder to spot. I spent hours on that one :-)Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#4Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#5Otherwise, a great read.
PS– Is it just me or is LLVM coming up more and more these days?
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#6Why does LLVM generate "ud2" instructions? WTF?
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#7Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#8It would be nice to have a code snippet for each of the examples. I'm a fairly experienced C++ developer but my knowledge of compilers is, admittedly, lacking and I just want to make sure I'm on the same page. Otherwise, a great read. PS– Is it just me or is LLVM coming up more and more these days?
- http://lkml.org/lkml/2009/7/17/187
- http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6...
I've put a gist file demonstrating the problem: https://gist.github.com/968723
#include
struct agnx_priv {
char demo;
};
struct ieee80211_hw {
struct agnx_priv *priv;
};
struct pci_dev {
struct ieee80211_hw* dev;
};
struct ieee80211_hw* pci_get_drvdata(struct pci_dev *pdev) {
if(!pdev)
return NULL;
return pdev->dev;
}
static void agnx_pci_remove (struct pci_dev *pdev)
{
struct ieee80211_hw *dev = pci_get_drvdata(pdev);
struct agnx_priv *priv = dev->priv;
if (!dev) return;
// This will segfault if the previous if is optimized
printf("%c\n", priv->demo);
}
int main(int argc, char **argv)
{
// (struct pci_dev *)argv[1] is just to avoid compiler optimisations
// =~ NULL if no args are passed.
struct pci_dev * pdev = (struct pci_dev *)argv[1];
agnx_pci_remove(pdev);
return 0;
}
Compile with: gcc -O2 -ggdb -Wall -Wundef -fno-strict-aliasing \
-fno-common -fdelete-null-pointer-checks test-deref.c \
-o test-deref
and gcc -O2 -ggdb -Wall -Wundef -fno-strict-aliasing \
-fno-common -fno-delete-null-pointer-checks test-deref.c \
-o test-derefRe: What Every C Programmer Should Know About Undefined Behavior #1/3
#9Why does LLVM generate "ud2" instructions? WTF?
Because it can. This is undefined behavior we are talking about.
"Raises an invalid opcode exception in all operating modes."
What is here undefined? LLVM must not generate such instructions except it it really wants such a exception. (Like Linux's panic() does on x86)
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#10Earlier quoted context omitted.
Because it can. This is undefined behavior we are talking about.
Sorry, I don't get it. The Intel manual says on UD2: "Raises an invalid opcode exception in all operating modes." What is here undefined? LLVM must not generate such instructions except it it really wants such a exception. (Like Linux's panic() does on x86)