News for hackers. Stuff that matters.
Re:The Following Code Causes Segfault in Clang by lindig on Sunday August 03, 2014 @04:32AM (#8127440)
If your are looking for code to break a C compiler, you can try my tool Quest https://github.com/lindig/quest. It tries to to generate code that shows that a C compiler handles parameter passing wrong. I usually run it in a loop, like here on Mac OS X 10.9.4 witch gcc:

    :quest $ gcc --version
     Configured with: --prefix=/Library/Developer/CommandLineTools/usr  --with-gxx-include-dir=/usr/include/c++/4.2.1
     Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
     Target: x86_64-apple-darwin13.3.0
     Thread model: posix

    :quest $ while true; do 
     > ./main.native -test gcc -n 1 > foo.c
     > gcc -O2 -o foo foo.c 
     > ./foo || break
     > echo -n .
     > done
     ................................................................
     ................................................................
     .................................................
     Assertion failed: (b32 == b43), function callee_b0f, file foo.c, line 128.
     Abort trap: 6
This means the tool found C code where parameter passing is not compiled properly. It took about 10 seconds to find this. The test case is pretty small:

    :quest $ wc foo.c 
	 140     444    3485 foo.c
The generated code that where the assertion checks that parameters are received correctly looks like this:

    static
    union bt8 *
    callee_b0f(struct bt4 *bp7,
	double *bp8,
	struct bt6 bp9,
	float bp10,
	struct bt7 bp11,
	double bp12,
	short int bp13,
	...)
    {
	va_list ap;
	typedef int bd0;
	typedef struct bt0 bd1;
	typedef int bd2;
	typedef union bt3 bd3;
	bd0 b41;
	bd1 b42;
	bd2 b43;
	bd3 b44;
	
	/* seed: 2040 */
	va_start(ap, bp13);
	QUEST_ASSERT(b34 == bp7);
	QUEST_ASSERT(b35 == bp8);
	QUEST_ASSERT(b36.b24.b18 == bp9.b24.b18);
	QUEST_ASSERT(b36.b24.b19 == bp9.b24.b19);
	QUEST_ASSERT(b36.b24.b20 == bp9.b24.b20);
	QUEST_ASSERT(b36.b24.b21 == bp9.b24.b21);
	QUEST_ASSERT(b36.b24.b22 == bp9.b24.b22);
	QUEST_ASSERT(b36.b24.b23 == bp9.b24.b23);
	QUEST_ASSERT(b36.b25 == bp9.b25);
	QUEST_ASSERT(b36.b26 == bp9.b26);
	QUEST_ASSERT(b37 == bp10);
	QUEST_ASSERT(b38.b27 == bp11.b27);
	QUEST_ASSERT(b39 == bp12);
	QUEST_ASSERT(b40 == bp13);
	b41 = va_arg(ap, bd0);
	b42 = va_arg(ap, bd1);
	b43 = va_arg(ap, bd2);
	b44 = va_arg(ap, bd3);
	QUEST_ASSERT(b30 == b41);
	QUEST_ASSERT(b31.b0 == b42.b0);
	QUEST_ASSERT(b32 == b43);
	QUEST_ASSERT(b33.b10.b1 == b44.b10.b1);
	va_end(ap);
	return b29;
    }
Re:The Following Code Causes Segfault in Clang by danieljh on Saturday August 02, 2014 @05:55PM (#8126199)
While we're at segfaulting compiler's, here's what I found just a few days ago:

    python -S -c 'print("void f(){} int main(){return (" + "*"*10**7 + "f)();}")' | gcc -xc -
(This is legal C -- look it up. Don't argue with me over the practical relevance of this please)
Re:The Following Code Causes Segfault in Clang by deathanatos on Saturday August 02, 2014 @06:51PM (#8126333)
I will point out that there is a section called "Translation limits" that discusses how compilers can't really be excepted to compile every legal program, because they run in a machine with a finite amount of memory.

> Both the translation and execution environments constrain the implementation of language translators and libraries. The following summarizes the language-related environmental limits on a conforming implementation; the library-related limits are discussed in clause 7.

> The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits:

> 4095 characters in a logical source line

Of course, it notes:

> Implementations should avoid imposing fixed translation limits whenever possible.

Note that these aren't strict limits, and don't really have an effect on the legality of your program, I feel it's more of a discussion of the limits imposed by reality, and what compilers must handle at a bare minimum.

And honestly, I would hope most modern compilers would do better than the noted limits and I'd also hope for a decent error message, not "gcc: internal compiler error: Segmentation fault (program cc1)" (which is what the program generates).

Last,

> This is legal C

Is it? You're returning the result of a function that returns void in a function that returns int (and even if main were void, I still don't think that's legal). Were gcc able to handle the abusive number of stars, it would say,

    <stdin>: In function ‘main’:
    <stdin>:1:23: error: void value not ignored as it ought to be
(which is what it says if you remove some of the stars.) Granted, this can be corrected, and your example will still cause the same output. (Which doesn't seem nearly as interesting as the linked C++ code. I'd like to know why that causes a segfault. With yours, I'd like to know why you were doing that.)
Re:The Following Code Causes Segfault in Clang by danieljh on Saturday August 02, 2014 @07:21PM (#8126391)
You are right in that the return is wrong and accidentally stayed in during example reduction down to a smaller version. Without it, the result is still the same.

The reason I was testing this was a discussion on IRC about functions decaying to pointer to functions, such that they are endlessly dereferenceable. The snippet above crashes GCC -- hard.

So, while the implementation is free not to handle 10^7 dereferencing operations, I'm not sure a hard crash is the right answer.

Here's a version without the return and using a lambda to shorten it further:

    python -S -c 'print("int main(){(" + "*"*10**7 + "+[]{})();}")' | g++ -std=c++11 -xc++ -
Re:The Following Code Causes Segfault in Clang by userbinator on Saturday August 02, 2014 @09:59PM (#8126755)
Depending on available memory, attempting to compile an expression with ridiculously large numbers of nested parentheses (e.g. "return (((...(42)...)));" will also do the trick.

I don't expect a compiler to be able to compile programs that exceed its internal limits, but a better error message would be much appreciated, instead of a hard crash. For comparison, with MSVC the parent's code produces

    fatal error C1026: parser stack overflow, program too complex
and the nested parentheses results in

    fatal error C1013: compiler limit : too many open parentheses
Re:The Following Code Causes Segfault in Clang by dbaupp on Saturday August 02, 2014 @09:45PM (#8126716)
This segfaults too, so it's "just" a problem of too many dereferences.

  python -c 'print ("int main(){" + "*" * (10**6) + "}")' | gcc -x c -
Re:The Following Code Causes Segfault in Clang by webkike on Saturday August 02, 2014 @06:52PM (#8126334)
Sure it's legal, but the bug you are demonstrating is uninteresting. It may not even technically be a violation of the C standard
Re:The Following Code Causes Segfault in Clang by a3_nm on Saturday August 02, 2014 @08:23PM (#8126564)
The error message is unhelpful and requests the user to submit a bug report. I would argue this is not good behavior no matter how absurd the input is.
Re:The Following Code Causes Segfault in Clang by gizmo686 on Saturday August 02, 2014 @06:17PM (#8126262)
What were you doing that lead to you finding this?
Re:The Following Code Causes Segfault in Clang by Torn on Saturday August 02, 2014 @06:19PM (#8126266)
printing lots of stars?
Re:The Following Code Causes Segfault in Clang by deathanatos on Saturday August 02, 2014 @06:35PM (#8126299)
The C program doesn't print stars. It appears to just call f. It just dereferences f quite a bit before eventually calling it. (He's printing stars in Python simply because it's a more concise way to represent a million stars.)
Re:The Following Code Causes Segfault in Clang by chrisdevereux on Saturday August 02, 2014 @06:43PM (#8126318)
Stack overflow?
Re:The Following Code Causes Segfault in Clang by danieljh on Saturday August 02, 2014 @07:55PM (#8126489)
Yes, you're able to confirm this by setting:

    ulimit -s unlimited
Re:The Following Code Causes Segfault in Clang by archgoon on Saturday August 02, 2014 @06:39PM (#8126306)
Hmm...

    Unable to find instantiation of declaration!
    UNREACHABLE executed at SemaTemplateInstantiateDecl.cpp:4384!
Not quite so unreachable...

https://gist.github.com/cwgreene/d689f010619310dbbc77

https://github.com/llvm-mirror/clang/blob/b310439121c875937d...

Re:The Following Code Causes Segfault in Clang by udp on Saturday August 02, 2014 @07:48PM (#8126467)
Something I found last week that crashes with clang-503.0.40:

    template<class T> class foo
    {
    public:

        ~ foo()
        {
        }

        foo &operator = (const foo &rhs)
        {
            foo::~foo();
            new (this) foo (rhs);

            return *this;
        }
    };

    int main(int argc, char * argv[])
    {
        foo<int> a, b;
        b = a;
    }
Re:The Following Code Causes Segfault in Clang by archgoon on Saturday August 02, 2014 @11:47PM (#8126952)
This is the same bug.
Re:The Following Code Causes Segfault in Clang by hamburglar on Saturday August 02, 2014 @05:44PM (#8126171)
Is there some legitimate reason to want to have A's destructor called twice on a single instance?
Re:The Following Code Causes Segfault in Clang by plorkyeran on Saturday August 02, 2014 @06:00PM (#8126213)
The usual reason for explicitly calling the destructor is if you then follow it up with a call to placement new to construct a new object in the same memory, but presumably that part was not relevant to the crash and so was not included in the minimal test case.
Re:The Following Code Causes Segfault in Clang by misnome on Saturday August 02, 2014 @06:00PM (#8126211)
Probably not, but the compiler crashing isn't a good way of notifying the user of that!
Re:The Following Code Causes Segfault in Clang by hamburglar on Monday August 04, 2014 @08:07PM (#8134804)
Ah, I didn't realize the segfault was in the compiler itself. The title ("segmentation fault on calling destructor in member function") made it sound like the generated code crashed. Now that there's a gist of a callstack it's clearer.
Re:The Following Code Causes Segfault in Clang by jey on Saturday August 02, 2014 @05:55PM (#8126197)
Yeah, maybe this is just a standard-conforming implementation of undefined behavior.
Re:The Following Code Causes Segfault in Clang by timshen on Saturday August 02, 2014 @07:21PM (#8126393)
It's nothing to do with standard-conforming or not. A correct implementation shall never crash.
Re:The Following Code Causes Segfault in Clang by Pacabel on Saturday August 02, 2014 @08:45PM (#8126601)
That's a pretty broad and idealistic claim to be making.

"Correctness" itself isn't an absolute. While something either does or does not conform to whatever has been defined as "correct", it's perfectly fine for the defined "correct" behavior in a given situation to be a crash.

In some cases a crash is the best that can be hoped for. Continuing on, even in an attempt to handle the failure more gracefully, can potentially be more harmful than just crashing.

Re:The Following Code Causes Segfault in Clang by mikeash on Saturday August 02, 2014 @09:45PM (#8126718)
I think you're confusing a crash in the generated program with a crash in the compiler itself. The latter is what's happening here.
Re:The Following Code Causes Segfault in Clang by jwatte on Saturday August 02, 2014 @11:06PM (#8126892)
There is lots of undefined behavior that causes crashing, although usually of the target program, not the compiler. Crashing compilers is nothing new though. I can't count how many ICEs I used to run into in certain versions of certain other compilers...
Re:The Following Code Causes Segfault in Clang by andrewchambers on Saturday August 02, 2014 @06:21PM (#8126270)
Something tells me C++ isn't the best thing to implement a compiler with.
Re:The Following Code Causes Segfault in Clang by millstone on Saturday August 02, 2014 @08:01PM (#8126503)
This looks to be an assertion failure, i.e. code that was thought to be unreachable is not. So there's no evidence that any of the negatives of C++ (memory safety, etc.) are in play here.
Re:The Following Code Causes Segfault in Clang by andrewchambers on Saturday August 02, 2014 @09:58PM (#8126752)
If that's the case I was being too harsh on clang.
Re:The Following Code Causes Segfault in Clang by andrewchambers on Saturday August 02, 2014 @10:12PM (#8126782)
I guess I was being to harsh on the memory issues in C++.

In practice it is a non issue, because build scripts can run arbitrary code long before a memory corruption in the system compiler. And if you plan on running the code you just compiled, you must already trust the code.

Unless of course its a segfault in LLVM and not just clang. LLVM is used for JIT in web browsers now, not that there are really any suitable replacements for C++ right now.

Re:The Following Code Causes Segfault in Clang by golemotron on Saturday August 02, 2014 @08:05PM (#8126518)
I modded you up because clang is written in C++ and even if I didn't know this I'd suspect it because segfaults in languages that are not weakly typed (i.e., C and C++) are incredibly rare.

There are better languages to write compilers in. OCaml is one.

Re:The Following Code Causes Segfault in Clang by timshen on Saturday August 02, 2014 @09:52PM (#8126736)
I'd rather say that C++ "fixes" C's unsafe type system by making some of the castings legal, instead of safer :)
Re:The Following Code Causes Segfault in Clang by nly on Saturday August 02, 2014 @09:07PM (#8126643)
C++ probably isn't 'weakly typed', whatever that means.
Re:The Following Code Causes Segfault in Clang by yzzxy on Saturday August 02, 2014 @09:20PM (#8126672)
You probably aren't "qualified to make that statement", if you don't know what weak typing is and are too lazy to google it.
Re:The Following Code Causes Segfault in Clang by nly on Sunday August 03, 2014 @09:21AM (#8127827)
https://en.wikipedia.org/wiki/Strong_and_weak_typing

> In general, these terms do not have a precise definition. Rather, they tend to be used by advocates or critics of a given programming language, as a means of explaining why a given language is better or worse than alternatives.

Re:The Following Code Causes Segfault in Clang by mateo411 on Saturday August 02, 2014 @10:34PM (#8126832)
C is weakly typed, because you can cast or set any variable to be a void *. Since C is weakly typed, then you can write a C++ program that is also weakly typed.
Re:The Following Code Causes Segfault in Clang by Tloewald on Saturday August 02, 2014 @07:43PM (#8126456)
FYI: someone has modded you down because the compiler is crashing when it compiles the C++ code, not because it is written in any particular language.
Re:The Following Code Causes Segfault in Clang by andrewchambers on Saturday August 02, 2014 @10:17PM (#8126793)
I'm aware, I care because LLVM is being integrated in web browsers as part of the JIT engine, and clang uses LLVM as its backend. So any segfaults related to LLVM (though not this one in particular) make me worried about browser security.
Re:The Following Code Causes Segfault in Clang by darkpore on Sunday August 03, 2014 @05:32AM (#8127510)
lol - you're aware that most web browsers are written in C++?
Re:The Following Code Causes Segfault in Clang by andrewchambers on Sunday August 03, 2014 @07:30AM (#8127655)
Painfully aware.

You do understand what an ever increasing attack surface does?