-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
zig cc: Compiling with rdynamic and fvisibility options fails to find symbols #9701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Interesting. I stepped through the execution with GDB and found that in the |
Here's a minimal reproduction: int main() {
int *traversal = 0;
*(++traversal) = 0;
return 0;
} $ zig cc issue.c
$ ./a.out
Illegal instruction (core dumped) main:
push rbp
mov rbp,rsp
ud1 eax,DWORD PTR [eax+0x13]
int3
int3
int3
int3
int3
int3
int3 The main: # @main
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], 0
mov qword ptr [rbp - 16], 0
mov rax, qword ptr [rbp - 16]
mov rcx, rax
add rcx, 4
mov qword ptr [rbp - 16], rcx
mov dword ptr [rax + 4], 0
xor eax, eax
pop rbp
ret |
Ok it looks like clang will also produce this undefined instruction with the following compilation options:
main: # @main
ud1 eax, dword ptr [eax + 19] I found this combination of clang options by using This is looking like it might be a bug with Clang. We should confirm this and if true create an issue upstream. |
By the way you can get around this issue by disabling undefined behavior sanitization:
This brings me to an error about
|
This isn't a bug, dereferencing null is UB in C++, right? |
That looks like legitimate UB that UBSan is catching to me. Try building with |
@N00byEdge yes it looks like I minimized the example too much. The original code that causes the undefined instruction is not dereferencing NULL. The actual UB comes from this code: static void push_traversal_node(void *lhs, void *rhs, int32_t index2) {
JanetTraversalNode node;
node.self = (JanetGCObject *) lhs;
node.other = (JanetGCObject *) rhs;
node.index = 0;
node.index2 = index2;
if (janet_vm.traversal + 1 >= janet_vm.traversal_top) {
size_t oldsize = janet_vm.traversal - janet_vm.traversal_base;
size_t newsize = 2 * oldsize + 1;
if (newsize < 128) {
newsize = 128;
}
JanetTraversalNode *tn = janet_realloc(janet_vm.traversal_base, newsize * sizeof(JanetTraversalNode));
if (tn == NULL) {
JANET_OUT_OF_MEMORY;
}
janet_vm.traversal_base = tn;
janet_vm.traversal_top = janet_vm.traversal_base + newsize;
janet_vm.traversal = janet_vm.traversal_base + oldsize;
}
*(++janet_vm.traversal) = node;
} I minified this again and came up with this: int main() {
int *start = 0;
int *next = start + 1;
return 0;
} Relating this back to the original code, it looks like the problem occurs when you perform a pointer/int addition and the pointer is set to 0 (or if (janet_vm.traversal + 1 >= janet_vm.traversal_top) { It appears this is where the UB occurs, since when the janet VM is initialized |
Thanks for @MasterQ32 , he informed me that pointer arithmetic on a NULL pointer is UB. So this is not a bug with clang. One thing to note is that the user experience that comes from |
Yeah definitely would be the case, but that sounds like a lot of effort just for another language than the compiler is targetting. Sounds like something that could be achieved by creating ubsan hooks in zig though instead of using traps/ud, so may not be that bad when using llvm. |
@marler8997 thank you for the quick response and your research! I successfully used your suggested command to build the binary, and since this is a bug in Janet source code, I believe the issue can be closed. |
I'm trying to compile https://github.com/janet-lang/janet on version v1.17.1 with latest zig 0.8.1 (same for 0.8.0). It works with gcc and clang. I use arch linux x64_86.
Steps to reproduce:
git clone https://github.com/janet-lang/janet
cd janet
git checkout v1.17.1
make CC='zig cc'
Output
make CC='zig cc'
Output
Formatting is a bit off, github interprets `>>>` as a quoteThe text was updated successfully, but these errors were encountered: