Live data from Hacker News

What Every C Programmer Should Know About Undefined Behavior #1/3

blog.llvm.org

1–10 of 19 posts

Re: What Every C Programmer Should Know About Undefined Behavior #1/3

#2
I 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.

Re: What Every C Programmer Should Know About Undefined Behavior #1/3

#3
post #2

I 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.

I had a similar bug. Using a tracing framework of macros, I had something like:

    #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

#5
It 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?

Re: What Every C Programmer Should Know About Undefined Behavior #1/3

#8
post #5

It 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?

There's this patch from the linux-kernel:

- 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-deref

Re: What Every C Programmer Should Know About Undefined Behavior #1/3

#9

Why does LLVM generate "ud2" instructions? WTF?

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)

Re: What Every C Programmer Should Know About Undefined Behavior #1/3

#10

Earlier 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)

To make him or her aware of the issue? I'd rather have my program crash at a well identifiable point in the execution flow than start acting rogue for no obvious reason (in both debug and production environments).
Post reply on HN