mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
Comment on gem5's broken GDB on secondary core
Try to assert on all C programs if thread creation failed. C++ already throws by default.
This commit is contained in:
16
README.adoc
16
README.adoc
@@ -2391,6 +2391,8 @@ to switch between two simultaneous live threads with different affinities, it ju
|
|||||||
b main_thread_0
|
b main_thread_0
|
||||||
....
|
....
|
||||||
|
|
||||||
|
Note that secondary cores in gem5 are kind of broken however: <<gem5-gdb-step-debug-secondary-cores>>.
|
||||||
|
|
||||||
Bibliography:
|
Bibliography:
|
||||||
|
|
||||||
* https://stackoverflow.com/questions/10490756/how-to-use-sched-getaffinity-and-sched-setaffinity-in-linux-from-c/50117787#50117787
|
* https://stackoverflow.com/questions/10490756/how-to-use-sched-getaffinity-and-sched-setaffinity-in-linux-from-c/50117787#50117787
|
||||||
@@ -11509,6 +11511,20 @@ TODO:
|
|||||||
|
|
||||||
breaks when `m5` is run on guest, but does not show the source code.
|
breaks when `m5` is run on guest, but does not show the source code.
|
||||||
|
|
||||||
|
==== gem5 GDB step debug secondary cores
|
||||||
|
|
||||||
|
gem5's secondary core GDB setup is a hack and spawns one gdbserver for each core in separate ports, e.g. 7000, 7001, etc.
|
||||||
|
|
||||||
|
Partly because of this, it is basically unusable/very hard to use, because you can't attach to a core that is stopped either because it hasn't been initialized, or if you are already currently debugging another core.
|
||||||
|
|
||||||
|
This affects both full system and <<gdb-step-debug-multicore-userland,userland>>, and is described in more detail at: https://gem5.atlassian.net/browse/GEM5-626
|
||||||
|
|
||||||
|
In LKMC 0a3ce2f41f12024930bcdc74ff646b66dfc46999, we can easily test attaching to another core by passing `--run-id`, e.g. to connect to the second core we can use `--run-id 1`:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run-gdb --arch aarch64 --emulator gem5 --userland userland/gcc/busy_loop.c --run-id 1
|
||||||
|
....
|
||||||
|
|
||||||
=== gem5 checkpoint
|
=== gem5 checkpoint
|
||||||
|
|
||||||
Analogous to QEMU's <<snapshot>>, but better since it can be started from inside the guest, so we can easily checkpoint after a specific guest event, e.g. just before `init` is done.
|
Analogous to QEMU's <<snapshot>>, but better since it can be started from inside the guest, so we can easily checkpoint after a specific guest event, e.g. just before `init` is done.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* https://cirosantilli.com/linux-kernel-module-cheat#atomic-c */
|
/* https://cirosantilli.com/linux-kernel-module-cheat#atomic-c */
|
||||||
|
|
||||||
#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
|
#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
|
||||||
|
#include <assert.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
@@ -36,9 +37,9 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
threads = malloc(sizeof(thrd_t) * nthreads);
|
threads = malloc(sizeof(thrd_t) * nthreads);
|
||||||
for(size_t i = 0; i < nthreads; ++i)
|
for(size_t i = 0; i < nthreads; ++i)
|
||||||
thrd_create(threads + i, my_thread_main, &niters);
|
assert(thrd_create(threads + i, my_thread_main, &niters) == thrd_success);
|
||||||
for(size_t i = 0; i < nthreads; ++i)
|
for(size_t i = 0; i < nthreads; ++i)
|
||||||
thrd_join(threads[i], NULL);
|
assert(thrd_join(threads[i], NULL) == thrd_success);
|
||||||
free(threads);
|
free(threads);
|
||||||
printf("atomic %u\n", acnt);
|
printf("atomic %u\n", acnt);
|
||||||
printf("non-atomic %u\n", cnt);
|
printf("non-atomic %u\n", cnt);
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ int main(void) {
|
|||||||
enum NUM_THREADS {NUM_THREADS = 2};
|
enum NUM_THREADS {NUM_THREADS = 2};
|
||||||
pthread_t threads[NUM_THREADS];
|
pthread_t threads[NUM_THREADS];
|
||||||
int thread_args[NUM_THREADS];
|
int thread_args[NUM_THREADS];
|
||||||
pthread_create(&threads[0], NULL, main_thread_0, (void*)&thread_args[0]);
|
assert(!pthread_create(&threads[0], NULL, main_thread_0, (void*)&thread_args[0]));
|
||||||
pthread_create(&threads[1], NULL, main_thread_1, (void*)&thread_args[1]);
|
assert(!pthread_create(&threads[1], NULL, main_thread_1, (void*)&thread_args[1]));
|
||||||
pthread_join(threads[0], NULL);
|
pthread_join(threads[0], NULL);
|
||||||
pthread_join(threads[1], NULL);
|
pthread_join(threads[1], NULL);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
/* Action */
|
/* Action */
|
||||||
for (i = 0; i < nthreads; ++i)
|
for (i = 0; i < nthreads; ++i)
|
||||||
pthread_create(&threads[i], NULL, main_thread, &niters);
|
assert(!pthread_create(&threads[i], NULL, main_thread, &niters));
|
||||||
for (i = 0; i < nthreads; ++i)
|
for (i = 0; i < nthreads; ++i)
|
||||||
pthread_join(threads[i], NULL);
|
assert(!pthread_join(threads[i], NULL));
|
||||||
assert(global == nthreads * niters);
|
assert(global == nthreads * niters);
|
||||||
|
|
||||||
/* Cleanup. */
|
/* Cleanup. */
|
||||||
|
|||||||
Reference in New Issue
Block a user