profiling: start

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2020-02-17 00:00:00 +00:00
parent f2713e69f6
commit fc98b543d1
2 changed files with 67 additions and 2 deletions

View File

@@ -3809,7 +3809,7 @@ Bibliography:
The ID is just hardcoded on the source:
==== stack smashing detected
==== stack smashing detected when using glibc
For some reason QEMU / glibc x86_64 picks up the host libc, which breaks things.
@@ -3871,7 +3871,7 @@ We pass `-L` by default, so everything just works.
However, in case something goes wrong, you can also try statically linked executables, since this mechanism tends to be a bit more stable, for example:
* QEMU x86_64 guest on x86_64 host was failing with <<stack-smashing-detected>>, but we found a workaround
* QEMU x86_64 guest on x86_64 host was failing with <<stack-smashing-detected-when-using-glibc>>, but we found a workaround
* gem5 user only supported static executables in the past, as mentioned at: xref:gem5-syscall-emulation-mode[xrefstyle=full]
Running statically linked executables sometimes makes things break:
@@ -14449,12 +14449,24 @@ Example:: link:userland/c/smash_stack.c[]
Leads to the dreadful "Stack smashing detected" message. Which is infinitely better than a silent break in any case.
We had also seen this error in our repository at: <<stack-smashing-detected-when-using-glibc>>.
==== Memory leaks
How to debug: https://stackoverflow.com/questions/6261201/how-to-find-memory-leak-in-a-c-code-project/57877190#57877190
Example: link:userland/c/memory_leak.c[]
==== Profiling userland programs
https://stackoverflow.com/questions/375913/how-can-i-profile-c-code-running-on-linux/60265409#60265409
OK, we have to learn this stuff.
Examples:
* link:userland/gcc/profile.c[]: simple profiling example, where certain calls of a certain function can dominate the runtime
=== Interpreted languages
Maybe some day someone will use this setup to study the performance of interpreters.

53
userland/gcc/profile.c Normal file
View File

@@ -0,0 +1,53 @@
/* https://cirosantilli.com/linux-kernel-module-cheat#profiling-userland-programs */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
uint64_t __attribute__ ((noinline)) common(uint64_t n, uint64_t seed) {
for (uint64_t i = 0; i < n; ++i) {
seed = (seed * seed) - (3 * seed) + 1;
}
return seed;
}
uint64_t __attribute__ ((noinline)) fast(uint64_t n, uint64_t seed) {
uint64_t max = (n / 10) + 1;
for (uint64_t i = 0; i < max; ++i) {
seed = common(n, (seed * seed) - (3 * seed) + 1);
}
return seed;
}
uint64_t __attribute__ ((noinline)) maybe_slow(uint64_t n, uint64_t seed, int is_slow) {
uint64_t max = n;
if (is_slow) {
max *= 10;
}
for (uint64_t i = 0; i < max; ++i) {
seed = common(n, (seed * seed) - (3 * seed) + 1);
}
return seed;
}
int main(int argc, char **argv) {
uint64_t n, seed;
if (argc > 1) {
n = strtoll(argv[1], NULL, 0);
} else {
n = 1;
}
if (argc > 2) {
seed = strtoll(argv[2], NULL, 0);
} else {
seed = 0;
}
seed += maybe_slow(n, seed, 0);
seed += fast(n, seed);
seed += maybe_slow(n, seed, 1);
seed += fast(n, seed);
seed += maybe_slow(n, seed, 0);
seed += fast(n, seed);
printf("%" PRIX64 "\n", seed);
return EXIT_SUCCESS;
}