How do I create symbol table of luaJIT-compiled code - perf

I want use linux-perf tools record lua stack, but don't spawn /tmp/per-{pid}.map file.
I build luajit lib from source code, and define Macro "LUAJIT_USE_PERFTOOLS" in the /root/luajit-2.0/src/lj_trace.c. I reference this file and use perf record lua program, not create symbol table.
luajit-2.0/src/lj_trace.c reference.
#ifdef LUAJIT_USE_PERFTOOLS
/*
** Create symbol table of JIT-compiled code. For use with Linux perf tools.
** Example usage:
** perf record -F 99 -e cycles luajit test.lua
** perf report -s symbol
** rm perf.data /tmp/perf-*.map
*/
#include <stdio.h>
My test.lua code.
function testlua()
print("hello world!")
end
while(true)
do
testlua()
end

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?

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.

addr2line - inline function code line missing

I have a android arm64 trace:
#02 pc 00000000000c61c0 /system/lib64/libmedia.so (_ZN7android10AudioTrack16AudioTrackThread10threadLoopEv+84)
I use below command to parser the code line information:
aarch64-linux-addr2line -f -C -e symbols/system/lib64/libmedia.so 00000000000c61cc
android::Condition::wait(android::Mutex&)
/proc/self/cwd/system/core/include/utils/Condition.h:106
Obviously, wait() is a inline function so addr2line didn't find the code line in threadLoop but use the wait() code line instead.
How to get the right line number in threadLoop? I am using binutils-2.28 to build addr2line tool.
Have you tried the -i option?
-i --inlines Unwind inlined functions

C/XCode: sh: ./child: No such file or directory. Command runs in terminal but not XCode

So I have a child.c file and I want to compile and run it in my main.c file using the system() function of stdlib.h.
child.c:
#include<stdio.h>
int main(){
printf("I am the child\n");
return 0;
}
main.c:
#include <stdio.h>
#include <stdlib.h>
int main() {
system("cd ~/Desktop/HW3/HW3");
system("gcc -o child child.c");
system("./child");
return 0;
}
everything worked fine when I compile and run main.c in terminal using the following command
abcs-mbp:HW3 abc$ cd
abcs-mbp:~ abc$ cd ~/Desktop/HW3/HW3
abcs-mbp:HW3 abc$ gcc -o main main.c
abcs-mbp:HW3 abc$ ./main
and it ran child.c and printed the following:
I am the child
but when I tried to run the exact same main.c in XCode, XCode gave me the following error:
clang: error: no such file or directory: 'child.c'
clang: error: no input files
sh: ./child: No such file or directory
anybody know why this is happening? I think it has something to do with path, but how can I tell XCode the path of child.c and then tell it to compile child.c?
I also tried
system("cd ~/Desktop/HW3/HW3");
system("gcc -o child child.c");
system("./child");
and
system("/Users/vqianxiao/Desktop/HW3/HW3/ gcc -o child child.c");
but nothing seems to work... any help is appreciated!
the reason that it does not work is a combination of things
1) each 'system' call is run in a separate shell instance,
so the second 'system' call
starts from the directory where the main program is running.
2) things do down from there
a suggested fix:
system("cd ~/Desktop/HW3/HW3; && gcc -o child child.c; && ./child;");
notice, all one system call, terminators at end of commands, and linked by && so one command must be successful to continue on to the next command

LLVM cannot find clang binary

I have just built and installed LLVM Clang 3.5.0 with compiler-rt. clang binary seems to work, but cannot build a simple test program:
$ cat hello.c
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World\n");
return 0;
}
Building it borks with error: unable to execute command: Executable "" doesn't exist!
$ clang hello.c -o hello
error: unable to execute command: Executable "" doesn't exist!
Executable "" ? Interesting...
Debugging it further reveals that clang tries to call itself to build .o object file and then ld to link it, but does not know where itself exists apparently.
$ clang -### hello.c -o hello
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-alpine-linux-musl
Thread model: posix
"" "-cc1" "-triple" "x86_64-alpine-linux-musl" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "hello.c" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-target-linker-version" "2.24" "-dwarf-column-info" "-resource-dir" "../lib/clang/3.5.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "../lib/clang/3.5.0/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/" "-ferror-limit" "19" "-fmessage-length" "158" "-mstackrealign" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-o" "/tmp/hello-37746e.o" "-x" "c" "hello.c"
"/usr/bin/ld" "-z" "relro" "--eh-frame-hdr" "-m" "elf_x86_64" "-dynamic-linker" "/lib/ld-musl-x86_64.so.1" "-o" "hello" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crt1.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crti.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/crtbegin.o" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../../x86_64-alpine-linux-musl/lib" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../.." "-L/../lib" "-L/lib" "-L/usr/lib" "/tmp/hello-37746e.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/crtend.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crtn.o"
When I run the first line putting /usr/bin/clang as the first item, it builds just fine:
$ /usr/bin/clang "-cc1" "-triple" "x86_64-alpine-linux-musl" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "hello.c" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-target-linker-version" "2.24" "-dwarf-column-info" "-resource-dir" "../lib/clang/3.5.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "../lib/clang/3.5.0/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/" "-ferror-limit" "19" "-fmessage-length" "158" "-mstackrealign" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-o" "/tmp/hello-4f64bb.o" "-x" "c" "hello.c"
$
And following /usr/bin/ld is able to link it just fine resulting in:
$ ./hello
Hello World
Anny suggestions what did I screw during configure/build?
clang source analysis shows that 'clang' program on Linux uses /proc/self/exe to find out real path of its binary. I am running in chroot without /proc mounted, thus it failed.
mount -t proc proc /proc
solves the issue

Resources