I want to use QEMU to run a multithreaded program, and I want to record the execution path of each thread in QEMU without modifying the source code, represented by the first address of the basic block. However, I have found that even in the QEMU user mode, even for multithreaded programs, I print CPU ->thread_ The id has always been the same value.
My work environment is Ubuntu 22.10.
I write a multithreaded program with c++ as follow:
#include <thread>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
void func1(){
while(1){
std::cout<<"thread 1\n";
sleep(1);
}
return;
}
void func2(){
while(1){
std::cout<<"thread 2\n";
sleep(1);
}
return;
}
void func3(){
while(1){
std::cout<<"thread 3\n";
sleep(1);
}
return;
}
void func4(){
while(1){
std::cout<<"thread 4\n";
sleep(1);
}
return;
}
int main(){
thread t1=thread(func1);
thread t2=thread(func2);
thread t3=thread(func3);
thread t4=thread(func4);
cout<<"this is main\n";
t1.join();
t2.join();
t3.join();
t4.join();
}
The version of qemu I used is 6.0.0,and I add some code in the /qemu-6.0.0/accel/tcg/ecp-exec.c file.
The function I operatored is cpu_tb_exec,the code I added as follow:
const void *tb_ptr = itb->tc.ptr;
+ static unsigned int count=0;
+ {
+ char filename[100]={0};
+ sprintf(filename,"/home/admin/work/qemu/log/log_%d",cpu->thread_id);
+ FILE *fp=fopen(filename,"a");
+ if(fp==NULL) {
+ exit(1);
+ }
+ lseek(fp,0,SEEK_END);
+ fprintf(fp,"%d: 0x%08x\n",count++,(unsigned long long)itb->pc);
+ fclose(fp);
+ }
//fprintf(stderr,"0x%08x\n",(unsigned long long)itb->pc);
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
"Trace %d: %p ["
TARGET_FMT_lx "/" TARGET_FMT_lx "/%#x] %s\n",
cpu->cpu_index, itb->tc.ptr,
itb->cs_base, itb->pc, itb->flags,
lookup_symbol(itb->pc));