FreeBSD Bugzilla – Attachment 219458 Details for
Bug 250954
ptrace(): weird ordering between inheriting debug registers and reporting a new thread
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Minimal demonstration program
thread-dbreg-test-pt.c (text/plain), 2.58 KB, created by
Michał Górny
on 2020-11-08 15:02:21 UTC
(
hide
)
Description:
Minimal demonstration program
Filename:
MIME Type:
Creator:
Michał Górny
Created:
2020-11-08 15:02:21 UTC
Size:
2.58 KB
patch
obsolete
>#include <assert.h> >#include <pthread.h> >#include <signal.h> >#include <stdio.h> >#include <unistd.h> >#include <sys/ptrace.h> >#include <sys/wait.h> >#include <machine/reg.h> > >volatile int g_val; >volatile int g_val2; > >void* thread_func(void* foo) { > return NULL; >} > >int main() { > int ret; > int pid = fork(); > assert(pid != -1); > if (pid == 0) { > int i; > pthread_t t2; > > ret = ptrace(PT_TRACE_ME, 0, NULL, 0); > assert(ret != -1); > // 2. wait for parent to set dbregs > raise(SIGSTOP); > > // 4. start new thread and stop immediately afterwards > ret = pthread_create(&t2, NULL, thread_func, NULL); > assert(ret == 0); > raise(SIGSTOP); > printf("thread started\n"); > > ret = pthread_join(t2, NULL); > assert(ret == 0); > printf("thread joined\n"); > _exit(0); > } > > // 1. wait for the child to start > pid_t waited = waitpid(pid, &ret, 0); > printf("wait: pid=%d, ret=%d\n", pid, ret); > assert(waited == pid); > assert(WSTOPSIG(ret) == SIGSTOP); > > // 3. set event mask & dbregs > int ev = PTRACE_LWP; > ret = ptrace(PT_SET_EVENT_MASK, pid, &ev, sizeof(ev)); > assert(ret != -1); > > struct dbreg db; > ret = ptrace(PT_GETDBREGS, pid, &db, 0); > assert(ret != -1); > > db.dr[0] = &g_val; > db.dr[7] = 0x303; > ret = ptrace(PT_SETDBREGS, pid, &db, 0); > assert(ret != -1); > > ret = ptrace(PT_CONTINUE, pid, (void*)1, 0); > assert(ret != -1); > > // 5. we should get SIGSTOP first, change dbregs > waited = waitpid(pid, &ret, 0); > printf("wait: pid=%d, ret=%d\n", pid, ret); > assert(waited == pid); > assert(WSTOPSIG(ret) == SIGSTOP); > > ret = ptrace(PT_GETDBREGS, pid, &db, 0); > assert(ret != -1); > > db.dr[0] = &g_val2; > db.dr[7] = 0x303; > ret = ptrace(PT_SETDBREGS, pid, &db, 0); > assert(ret != -1); > > ret = ptrace(PT_CONTINUE, pid, (void*)1, 0); > assert(ret != -1); > > // 6. now we should get new thread event > waited = waitpid(pid, &ret, 0); > printf("wait: pid=%d, ret=%d\n", pid, ret); > assert(waited == pid); > assert(WSTOPSIG(ret) == SIGTRAP); > > struct ptrace_lwpinfo info; > ret = ptrace(PT_LWPINFO, pid, &info, sizeof(info)); > assert(ret != -1); > printf("tid = %d\n", info.pl_lwpid); > > ret = ptrace(PT_GETDBREGS, info.pl_lwpid, &db, 0); > assert(ret != -1); > printf("dr0=%p, g_val=%p, g_val2=%p\n", db.dr[0], &g_val, &g_val2); > > ret = ptrace(PT_CONTINUE, pid, (void*)1, 0); > assert(ret != -1); > > // thread exited > waited = waitpid(pid, &ret, 0); > printf("wait: pid=%d, ret=%d\n", pid, ret); > assert(waited == pid); > assert(WSTOPSIG(ret) == SIGTRAP); > > ret = ptrace(PT_CONTINUE, pid, (void*)1, 0); > assert(ret != -1); > > waited = waitpid(pid, &ret, 0); > printf("wait: pid=%d, ret=%d\n", pid, ret); > assert(waited == pid); > assert(WIFEXITED(ret)); > > return 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 250954
:
219458
|
219480
|
219487