mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
profiling: start
This commit is contained in:
16
README.adoc
16
README.adoc
@@ -3809,7 +3809,7 @@ Bibliography:
|
|||||||
|
|
||||||
The ID is just hardcoded on the source:
|
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.
|
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:
|
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]
|
* 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:
|
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.
|
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
|
==== Memory leaks
|
||||||
|
|
||||||
How to debug: https://stackoverflow.com/questions/6261201/how-to-find-memory-leak-in-a-c-code-project/57877190#57877190
|
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[]
|
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
|
=== Interpreted languages
|
||||||
|
|
||||||
Maybe some day someone will use this setup to study the performance of interpreters.
|
Maybe some day someone will use this setup to study the performance of interpreters.
|
||||||
|
|||||||
53
userland/gcc/profile.c
Normal file
53
userland/gcc/profile.c
Normal 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user