Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
0a70783c
Commit
0a70783c
authored
Nov 08, 1999
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Preliminary ptrace support.
parent
c81226aa
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
138 additions
and
20 deletions
+138
-20
process.c
server/process.c
+3
-5
select.c
server/select.c
+9
-0
thread.c
server/thread.c
+115
-14
thread.h
server/thread.h
+11
-1
No files found.
server/process.c
View file @
0a70783c
...
...
@@ -256,8 +256,7 @@ void suspend_process( struct process *process )
struct
thread
*
thread
=
process
->
thread_list
;
for
(;
thread
;
thread
=
thread
->
proc_next
)
{
if
(
!
thread
->
suspend
&&
thread
->
unix_pid
)
kill
(
thread
->
unix_pid
,
SIGSTOP
);
if
(
!
thread
->
suspend
)
stop_thread
(
thread
);
}
}
}
...
...
@@ -271,8 +270,7 @@ void resume_process( struct process *process )
struct
thread
*
thread
=
process
->
thread_list
;
for
(;
thread
;
thread
=
thread
->
proc_next
)
{
if
(
!
thread
->
suspend
&&
thread
->
unix_pid
)
kill
(
thread
->
unix_pid
,
SIGCONT
);
if
(
!
thread
->
suspend
)
continue_thread
(
thread
);
}
}
}
...
...
@@ -350,7 +348,7 @@ DECL_HANDLER(init_process)
{
struct
new_process_request
*
info
;
if
(
current
->
state
==
STARTING
)
if
(
!
current
->
unix_pid
)
{
fatal_protocol_error
(
current
,
"init_process: init_thread not called yet
\n
"
);
return
;
...
...
server/select.c
View file @
0a70783c
...
...
@@ -15,6 +15,7 @@
#include <unistd.h>
#include "object.h"
#include "thread.h"
struct
timeout_user
{
...
...
@@ -165,6 +166,11 @@ static void sighup()
}
#endif
/* dummy SIGCHLD handler */
static
void
sigchld
()
{
}
/* server main loop */
void
select_loop
(
void
)
{
...
...
@@ -172,6 +178,7 @@ void select_loop(void)
setsid
();
signal
(
SIGPIPE
,
SIG_IGN
);
signal
(
SIGCHLD
,
sigchld
);
#ifdef DEBUG_OBJECTS
signal
(
SIGHUP
,
sighup
);
#endif
...
...
@@ -223,9 +230,11 @@ void select_loop(void)
if
(
do_dump_objects
)
dump_objects
();
do_dump_objects
=
0
;
#endif
wait4_thread
(
NULL
,
0
);
continue
;
}
perror
(
"select"
);
continue
;
}
for
(
i
=
0
;
i
<=
max_fd
;
i
++
)
...
...
server/thread.c
View file @
0a70783c
...
...
@@ -15,8 +15,10 @@
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdarg.h>
...
...
@@ -118,7 +120,8 @@ static struct thread *create_thread( int fd, struct process *process, int suspen
thread
->
apc
=
NULL
;
thread
->
apc_count
=
0
;
thread
->
error
=
0
;
thread
->
state
=
STARTING
;
thread
->
state
=
RUNNING
;
thread
->
attached
=
0
;
thread
->
exit_code
=
0x103
;
/* STILL_ACTIVE */
thread
->
next
=
NULL
;
thread
->
prev
=
NULL
;
...
...
@@ -223,16 +226,118 @@ static void set_thread_info( struct thread *thread,
}
}
/* find a thread from a Unix pid */
static
struct
thread
*
get_thread_from_pid
(
int
pid
)
{
struct
thread
*
t
=
first_thread
;
while
(
t
&&
(
t
->
unix_pid
!=
pid
))
t
=
t
->
next
;
return
t
;
}
/* wait for a ptraced child to get a certain signal */
/* if the signal is 0, we simply check if anything is pending and return at once */
void
wait4_thread
(
struct
thread
*
thread
,
int
signal
)
{
int
status
;
int
pid
;
restart:
pid
=
thread
?
thread
->
unix_pid
:
-
1
;
if
((
pid
=
wait4
(
pid
,
&
status
,
WUNTRACED
|
(
signal
?
0
:
WNOHANG
),
NULL
))
==
-
1
)
{
perror
(
"wait4"
);
return
;
}
if
(
WIFSTOPPED
(
status
))
{
int
sig
=
WSTOPSIG
(
status
);
if
(
debug_level
)
fprintf
(
stderr
,
"ptrace: pid %d got sig %d
\n
"
,
pid
,
sig
);
switch
(
sig
)
{
case
SIGSTOP
:
/* continue at once if not suspended */
if
(
!
thread
)
thread
=
get_thread_from_pid
(
pid
);
if
(
!
(
thread
->
process
->
suspend
+
thread
->
suspend
))
ptrace
(
PTRACE_CONT
,
pid
,
0
,
sig
);
break
;
default:
/* ignore other signals for now */
ptrace
(
PTRACE_CONT
,
pid
,
0
,
sig
);
break
;
}
if
(
signal
&&
sig
!=
signal
)
goto
restart
;
}
else
if
(
WIFSIGNALED
(
status
))
{
int
exit_code
=
WTERMSIG
(
status
);
if
(
debug_level
)
fprintf
(
stderr
,
"ptrace: pid %d killed by sig %d
\n
"
,
pid
,
exit_code
);
if
(
!
thread
)
thread
=
get_thread_from_pid
(
pid
);
if
(
thread
->
client
)
remove_client
(
thread
->
client
,
exit_code
);
}
else
if
(
WIFEXITED
(
status
))
{
int
exit_code
=
WEXITSTATUS
(
status
);
if
(
debug_level
)
fprintf
(
stderr
,
"ptrace: pid %d exited with status %d
\n
"
,
pid
,
exit_code
);
if
(
!
thread
)
thread
=
get_thread_from_pid
(
pid
);
if
(
thread
->
client
)
remove_client
(
thread
->
client
,
exit_code
);
}
else
fprintf
(
stderr
,
"wait4: pid %d unknown status %x
\n
"
,
pid
,
status
);
}
/* attach to a Unix thread */
static
int
attach_thread
(
struct
thread
*
thread
)
{
/* this may fail if the client is already being debugged */
if
(
ptrace
(
PTRACE_ATTACH
,
thread
->
unix_pid
,
0
,
0
)
==
-
1
)
return
0
;
if
(
debug_level
)
fprintf
(
stderr
,
"ptrace: attached to pid %d
\n
"
,
thread
->
unix_pid
);
thread
->
attached
=
1
;
wait4_thread
(
thread
,
SIGSTOP
);
return
1
;
}
/* detach from a Unix thread and kill it */
static
void
detach_thread
(
struct
thread
*
thread
)
{
if
(
!
thread
->
unix_pid
)
return
;
kill
(
thread
->
unix_pid
,
SIGTERM
);
if
(
thread
->
suspend
+
thread
->
process
->
suspend
)
continue_thread
(
thread
);
if
(
thread
->
attached
)
{
wait4_thread
(
thread
,
SIGTERM
);
if
(
debug_level
)
fprintf
(
stderr
,
"ptrace: detaching from %d
\n
"
,
thread
->
unix_pid
);
ptrace
(
PTRACE_DETACH
,
thread
->
unix_pid
,
0
,
SIGTERM
);
thread
->
attached
=
0
;
}
}
/* stop a thread (at the Unix level) */
void
stop_thread
(
struct
thread
*
thread
)
{
if
(
!
thread
->
unix_pid
)
return
;
/* first try to attach to it */
if
(
!
thread
->
attached
)
if
(
attach_thread
(
thread
))
return
;
/* this will have stopped it */
/* attached already, or attach failed -> send a signal */
kill
(
thread
->
unix_pid
,
SIGSTOP
);
if
(
thread
->
attached
)
wait4_thread
(
thread
,
SIGSTOP
);
}
/* make a thread continue (at the Unix level) */
void
continue_thread
(
struct
thread
*
thread
)
{
if
(
!
thread
->
unix_pid
)
return
;
if
(
!
thread
->
attached
)
kill
(
thread
->
unix_pid
,
SIGCONT
);
else
ptrace
(
PTRACE_CONT
,
thread
->
unix_pid
,
0
,
SIGSTOP
);
}
/* suspend a thread */
static
int
suspend_thread
(
struct
thread
*
thread
)
{
int
old_count
=
thread
->
suspend
;
if
(
thread
->
suspend
<
MAXIMUM_SUSPEND_COUNT
)
{
if
(
!
(
thread
->
process
->
suspend
+
thread
->
suspend
++
))
{
if
(
thread
->
unix_pid
)
kill
(
thread
->
unix_pid
,
SIGSTOP
);
}
if
(
!
(
thread
->
process
->
suspend
+
thread
->
suspend
++
))
stop_thread
(
thread
);
}
return
old_count
;
}
...
...
@@ -243,10 +348,7 @@ static int resume_thread( struct thread *thread )
int
old_count
=
thread
->
suspend
;
if
(
thread
->
suspend
>
0
)
{
if
(
!
(
--
thread
->
suspend
+
thread
->
process
->
suspend
))
{
if
(
thread
->
unix_pid
)
kill
(
thread
->
unix_pid
,
SIGCONT
);
}
if
(
!
(
--
thread
->
suspend
+
thread
->
process
->
suspend
))
continue_thread
(
thread
);
}
return
old_count
;
}
...
...
@@ -493,7 +595,6 @@ static int thread_queue_apc( struct thread *thread, void *func, void *param )
void
kill_thread
(
struct
thread
*
thread
,
int
exit_code
)
{
if
(
thread
->
state
==
TERMINATED
)
return
;
/* already killed */
if
(
thread
->
unix_pid
)
kill
(
thread
->
unix_pid
,
SIGTERM
);
remove_client
(
thread
->
client
,
exit_code
);
/* this will call thread_killed */
}
...
...
@@ -502,11 +603,13 @@ void thread_killed( struct thread *thread, int exit_code )
{
thread
->
state
=
TERMINATED
;
thread
->
exit_code
=
exit_code
;
thread
->
client
=
NULL
;
if
(
thread
->
wait
)
end_wait
(
thread
);
debug_exit_thread
(
thread
,
exit_code
);
abandon_mutexes
(
thread
);
remove_process_thread
(
thread
->
process
,
thread
);
wake_up
(
&
thread
->
obj
,
0
);
detach_thread
(
thread
);
release_object
(
thread
);
}
...
...
@@ -544,16 +647,14 @@ DECL_HANDLER(get_thread_buffer)
/* initialize a new thread */
DECL_HANDLER
(
init_thread
)
{
if
(
current
->
state
!=
STARTING
)
if
(
current
->
unix_pid
)
{
fatal_protocol_error
(
current
,
"init_thread: already running
\n
"
);
return
;
}
current
->
state
=
RUNNING
;
current
->
unix_pid
=
req
->
unix_pid
;
current
->
teb
=
req
->
teb
;
if
(
current
->
suspend
+
current
->
process
->
suspend
>
0
)
kill
(
current
->
unix_pid
,
SIGSTOP
);
if
(
current
->
suspend
+
current
->
process
->
suspend
>
0
)
stop_thread
(
current
);
req
->
pid
=
current
->
process
;
req
->
tid
=
current
;
}
...
...
server/thread.h
View file @
0a70783c
...
...
@@ -22,7 +22,13 @@ struct mutex;
struct
debug_ctx
;
struct
debug_event
;
enum
run_state
{
STARTING
,
RUNNING
,
SLEEPING
,
TERMINATED
};
enum
run_state
{
RUNNING
,
/* running normally */
SLEEPING
,
/* sleeping waiting for a request to terminate */
TERMINATED
/* terminated */
};
struct
thread
{
...
...
@@ -41,6 +47,7 @@ struct thread
int
apc_count
;
/* number of outstanding APCs */
int
error
;
/* current error code */
enum
run_state
state
;
/* running state */
int
attached
;
/* is thread attached with ptrace? */
int
exit_code
;
/* thread exit code */
struct
client
*
client
;
/* client for socket communications */
int
unix_pid
;
/* Unix pid of client */
...
...
@@ -59,6 +66,9 @@ extern struct thread *current;
extern
void
create_initial_thread
(
int
fd
);
extern
struct
thread
*
get_thread_from_id
(
void
*
id
);
extern
struct
thread
*
get_thread_from_handle
(
int
handle
,
unsigned
int
access
);
extern
void
wait4_thread
(
struct
thread
*
thread
,
int
wait
);
extern
void
stop_thread
(
struct
thread
*
thread
);
extern
void
continue_thread
(
struct
thread
*
thread
);
extern
void
suspend_all_threads
(
void
);
extern
void
resume_all_threads
(
void
);
extern
int
add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment