Program segfaults when compiled with clang but not gcc - clang

Summary: When I set the -mcmodel=large flag when compiling with clang my application segfaults when accessing thread local storage. This does not happen when compiling with gcc. Is this a bug with clang or something I am doing wrong?
Details:
The following code segment crashes when compiled with clang when setting the -mcmodel flag, but it runs fine when compiled with gcc
#include <stdio.h>
#include <pthread.h>
__thread int tlsTest;
int main(int argc, char **argv) {
printf("&tlsTest is %p\n", &tlsTest);
tlsTest = argc;
printf("tlsTest is %d\n", tlsTest);
return 0;
}
When I compile with: clang test.c -pthread -mcmodel=large the result is:
&tlsTest is 0x7fd24262c6fc
Segmentation fault (core dumped)
But with: gcc test.c -pthread -mcmodel=large the result is:
&tlsTest is 0x7f1cf785c6fc
tlsTest is 1
The program also works fine when compiled with: clang test.c -pthread
I read the following link about mcmodel but I'm not sure how this relates to the segfault that I've observed. Note that the problem occurs for -mcmodel=medium also, but not for -mcmodel=small.
Is this a bug with clang/llvm or is it a different interpretation of the standard or some unimplemented feature?
Also my system is Ubuntu 12.04. My version of gcc is 4.6.3 and the version of clang/llvm that I tested is a recent snapshot of 3.3 development, and I also tested with clang 3.2.

Related

Debug printf performance when compiled with clang cfi

Setup
I have a simple helloworld program:
// content of main.c
#include <stdio.h>
#include <limits.h>
int main() {
for (int i = 0; i < INT_MAX; ++i) {
printf("simply helloworld!\n");
}
return 0;
}
I compile a baseline version with clang 13.0.0 using clang -flto=thin -fvisibility=hidden -fuse-ld=lld main.c
To experiment with CFI, I compile another version using clang -flto=thin -fsanitize=cfi -fsanitize-cfi-cross-dso -fno-sanitize-cfi-canonical-jump-tables -fsanitize-trap=cfi -fvisibility=hidden -fuse-ld=lld main.c
Expectation
I am expecting negligible performance overhead as I am only calling into a shared library that I expect will run the same code for both. The disassembly for main function for both binaries look the same.
Reality
The baseline version completes execution in ~27s while the cfi version completes execution in ~32s. Using perf stat -e instructions <binary> I can see that the cfi version runs ~100,000,000,000 more instructions. With perf record then perf diff, I can see that the difference is primarily in two functions _pthread_cleanup_push_defer and _pthread_cleanup_pop_restore that the cfi version runs. Using gdb, these functions are called as the call stack of printf gets deeper.
Question
How do I begin to explain the performance difference between these two binaries? What makes a simple call to printf call two different versions of itself for two different binaries?

Undefined symbol in Clang-compiled Python extension using OpenMP

I am facing a weird problem when compiling a Python extension featuring OpenMP with Clang.
Minimal Example
I managed to boil down my actual problem to the following code:
The Python extension could not be much simpler, while still featuring OpenMP.
Apart from the function bar, this is mostly standard boilerplate:
# include <Python.h>
static PyObject * bar(PyObject *self)
{
#pragma omp parallel sections
{
#pragma omp section
{float x=42.0; x+=1;}
}
Py_RETURN_NONE;
}
static PyMethodDef foo_methods[] = {
{"bar", (PyCFunction) bar, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, "foo", NULL, -1,
foo_methods, NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_foo(void)
{
return PyModule_Create(&moduledef);
}
With the above being foo.c, I compile and load this with:
clang -fPIC -fopenmp -I/usr/include/python3.7m -c foo.c -o foo.o
clang -shared foo.o -o foo.so -lgomp
python3 -c "import foo"
The last line, i.e., the import of the module throws the following error:
ImportError: /home/wrzlprmft/…/foo.so: undefined symbol: __kmpc_for_static_fini
What I found out so far
This does not happen when replacing Clang with GCC.
This does not happen with regular shared libraries (not involving Python).
Using Setuptools to compile the extension does not help.
(In fact, my compile commands are a reduction of what Setuptools does to find out whether it uses any non-essential compiler extensions that cause this.)
All of this happens on Ubuntu 19.10 with Python 3.7, Clang 9.0.0-2, and GCC 9.2.1.
I can also replicate the problem on current Arch Linux with Python 3.8 and Clang 9.0.1.
This worked until a year ago, probably longer.
Using Python 3.6 does not help.
Using Clang 3.8, 4.0, 6.0, 7, or 8 does not help.
Here, somebody reports a similar problem when trying to compile TensorFlow.
This is yet unsolved.
Question
What is going wrong here and how can I fix this?
Right now I do not even have an idea whether this is an error by me, in Clang, OpenMP, or Python.

llvm-link error when using memcpy in C code and compiling with wasm target

I am trying to compile two *.c files to LLVM bitcode via clang, link them together using llvm-link, and make a single *.wasm file out of it. I built LLVM on my machine via the Makefile provided by https://github.com/yurydelendik/wasmception
This works fine until I use memcpy in the C code. Then llvm-link stops with error:
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* #llvm.memcpy.p0i8.p0i8.i32
The following is a minimal example to reproduce the issue:
one.c
#define EXPORT __attribute__((visibility("default")))
#include <string.h>
char* some_str();
EXPORT void do_something() {
char* cpy_src = some_str();
char other_str[15];
memcpy(other_str, cpy_src, strlen(cpy_src));
}
two.c
char* some_str() {
return "Hello World";
}
Execute the following commands:
$ clang --target=wasm32-unknown-unknown-wasm --sysroot=../wasmception/sysroot -S -emit-llvm -nostartfiles -fvisibility=hidden one.c -o one.bc
[...]
$ clang --target=wasm32-unknown-unknown-wasm --sysroot=../wasmception/sysroot -S -emit-llvm -nostartfiles -fvisibility=hidden two.c -o two.bc
[...]
Note that no optimization is done because that would eliminate the unnecessary memcpy call here. As I said, this is a minimal example out of context to show the error.
$ llvm-link one.bc two.bc -o res.bc -v
Loading 'one.bc'
Linking in 'one.bc'
Loading 'two.bc'
Linking in 'two.bc'
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* #llvm.memcpy.p0i8.p0i8.i32
llvm-link: error: linked module is broken!
When I comment out the memcpy call in the example file, the error is gone. Of course this is not an option in the real project I am working at.
Am I doing something wrong? Is it a bad idea in general to use memcpy in a WebAssembly context? Can this be a bug in LLVM/Clang?
Reading through these github issues, it seems the memcpy intrinsic is not currently supported by the WASM backend:
https://github.com/WebAssembly/design/issues/236
https://github.com/WebAssembly/design/issues/1003
As a workaround, you could instruct clang to disable intrinsic expansion using -fno-builtin, so that the generated code will call the actual memcpy function.

How / is it possible to build C "Hello world" program entirely static (OS X, Clang)?

Is it possible to compile C "Hello world" program to have final executable entirely static?
#include <stdio.h>
int main() {
printf("hello world!\n");
return 0;
}
I've tried the following:
clang -static main.c
But it gives:
ld: library not found for -lcrt0.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've seen staticly linked libc? but I want to get additional information on this topic.
P.S. I am asking this for education purposes rather than for real practice.

How do get uninitialzed variable warning from Clang 2.9?

I have this file:
#include <stdio.h>
int main(void)
{
int i;
printf("%d\n",i);
return 0;
}
If I compile with gcc 4.6.1 on Mint 12:
CC -Wall -O test_gcc.c
test_gcc.c: In function ‘main’:
test_gcc.c:8:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
Those same options with clang 2.9 do not give a warning.
The Clang online manual shows a -Weverything, but this version doesn't know about it
clang -Weverything test_gcc.c
warning: unknown warning option '-Weverything' [-Wunknown-warning-option]
also
clang -Wuninitialized test_gcc.c
does not give a warning
How would I get a warning for an uninitialized variable read in clang 2.9?
Get a newer version of clang; 2.9 is over a year old.

Resources