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
44699c32
Commit
44699c32
authored
Feb 02, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Add a separate request to initialize the first thread of a process.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
123023ea
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
265 additions
and
159 deletions
+265
-159
loader.c
dlls/ntdll/unix/loader.c
+1
-3
server.c
dlls/ntdll/unix/server.c
+114
-76
unix_private.h
dlls/ntdll/unix/unix_private.h
+2
-2
server_protocol.h
include/wine/server_protocol.h
+26
-5
process.c
server/process.c
+2
-3
process.h
server/process.h
+1
-1
protocol.def
server/protocol.def
+18
-6
request.h
server/request.h
+23
-13
thread.c
server/thread.c
+57
-46
trace.c
server/trace.c
+21
-4
No files found.
dlls/ntdll/unix/loader.c
View file @
44699c32
...
...
@@ -1618,7 +1618,6 @@ static struct unix_funcs unix_funcs =
*/
static
void
start_main_thread
(
void
)
{
BOOL
suspend
;
NTSTATUS
status
;
TEB
*
teb
=
virtual_alloc_first_teb
();
...
...
@@ -1626,8 +1625,7 @@ static void start_main_thread(void)
signal_alloc_thread
(
teb
);
signal_init_thread
(
teb
);
dbg_init
();
server_init_process
();
startup_info_size
=
server_init_thread
(
teb
->
Peb
,
&
suspend
);
startup_info_size
=
server_init_process
();
virtual_map_user_shared_data
();
init_cpu_info
();
init_files
();
...
...
dlls/ntdll/unix/server.c
View file @
44699c32
...
...
@@ -1413,14 +1413,61 @@ static int get_unix_tid(void)
/***********************************************************************
* init_thread_pipe
*
* Create the server->client communication pipe.
*/
static
int
init_thread_pipe
(
void
)
{
int
reply_pipe
[
2
];
stack_t
ss
;
ss
.
ss_sp
=
get_signal_stack
();
ss
.
ss_size
=
signal_stack_size
;
ss
.
ss_flags
=
0
;
sigaltstack
(
&
ss
,
NULL
);
if
(
server_pipe
(
reply_pipe
)
==
-
1
)
server_protocol_perror
(
"pipe"
);
if
(
server_pipe
(
ntdll_get_thread_data
()
->
wait_fd
)
==
-
1
)
server_protocol_perror
(
"pipe"
);
wine_server_send_fd
(
reply_pipe
[
1
]
);
wine_server_send_fd
(
ntdll_get_thread_data
()
->
wait_fd
[
1
]
);
ntdll_get_thread_data
()
->
reply_fd
=
reply_pipe
[
0
];
return
reply_pipe
[
1
];
}
/***********************************************************************
* init_teb64
*
* Initialize the 64-bit part of the TEB for WoW64 threads.
*/
static
void
init_teb64
(
TEB
*
teb
)
{
#ifndef _WIN64
TEB64
*
teb64
=
(
TEB64
*
)((
char
*
)
teb
-
teb_offset
);
if
(
!
is_wow64
)
return
;
teb
->
GdiBatchCount
=
PtrToUlong
(
teb64
);
teb
->
WowTebOffset
=
-
teb_offset
;
teb64
->
ClientId
.
UniqueProcess
=
PtrToUlong
(
teb
->
ClientId
.
UniqueProcess
);
teb64
->
ClientId
.
UniqueThread
=
PtrToUlong
(
teb
->
ClientId
.
UniqueThread
);
#endif
}
/***********************************************************************
* server_init_process
*
* Start the server and create the initial socket pair.
*/
void
server_init_process
(
void
)
size_t
server_init_process
(
void
)
{
obj_handle_t
version
;
static
const
char
*
cpu_names
[]
=
{
"x86"
,
"x86_64"
,
"PowerPC"
,
"ARM"
,
"ARM64"
};
const
char
*
arch
=
getenv
(
"WINEARCH"
);
const
char
*
env_socket
=
getenv
(
"WINESERVERSOCKET"
);
obj_handle_t
version
;
int
ret
,
reply_pipe
;
struct
sigaction
sig_act
;
size_t
info_size
;
server_pid
=
-
1
;
if
(
env_socket
)
...
...
@@ -1473,6 +1520,60 @@ void server_init_process(void)
/* work around Ubuntu's ptrace breakage */
if
(
server_pid
!=
-
1
)
prctl
(
0x59616d61
/* PR_SET_PTRACER */
,
server_pid
);
#endif
/* ignore SIGPIPE so that we get an EPIPE error instead */
sig_act
.
sa_handler
=
SIG_IGN
;
sig_act
.
sa_flags
=
0
;
sigemptyset
(
&
sig_act
.
sa_mask
);
sigaction
(
SIGPIPE
,
&
sig_act
,
NULL
);
reply_pipe
=
init_thread_pipe
();
SERVER_START_REQ
(
init_first_thread
)
{
req
->
unix_pid
=
getpid
();
req
->
unix_tid
=
get_unix_tid
();
req
->
teb
=
wine_server_client_ptr
(
NtCurrentTeb
()
);
req
->
peb
=
wine_server_client_ptr
(
NtCurrentTeb
()
->
Peb
);
req
->
reply_fd
=
reply_pipe
;
req
->
wait_fd
=
ntdll_get_thread_data
()
->
wait_fd
[
1
];
req
->
debug_level
=
(
TRACE_ON
(
server
)
!=
0
);
req
->
cpu
=
client_cpu
;
ret
=
wine_server_call
(
req
);
NtCurrentTeb
()
->
ClientId
.
UniqueProcess
=
ULongToHandle
(
reply
->
pid
);
NtCurrentTeb
()
->
ClientId
.
UniqueThread
=
ULongToHandle
(
reply
->
tid
);
info_size
=
reply
->
info_size
;
server_start_time
=
reply
->
server_start
;
server_cpus
=
reply
->
all_cpus
;
}
SERVER_END_REQ
;
close
(
reply_pipe
);
#ifndef _WIN64
is_wow64
=
(
server_cpus
&
((
1
<<
CPU_x86_64
)
|
(
1
<<
CPU_ARM64
)))
!=
0
;
init_teb64
(
NtCurrentTeb
()
);
#endif
switch
(
ret
)
{
case
STATUS_SUCCESS
:
if
(
arch
)
{
if
(
!
strcmp
(
arch
,
"win32"
)
&&
(
is_win64
||
is_wow64
))
fatal_error
(
"WINEARCH set to win32 but '%s' is a 64-bit installation.
\n
"
,
config_dir
);
if
(
!
strcmp
(
arch
,
"win64"
)
&&
!
is_win64
&&
!
is_wow64
)
fatal_error
(
"WINEARCH set to win64 but '%s' is a 32-bit installation.
\n
"
,
config_dir
);
}
return
info_size
;
case
STATUS_INVALID_IMAGE_WIN_64
:
fatal_error
(
"'%s' is a 32-bit installation, it cannot support 64-bit applications.
\n
"
,
config_dir
);
case
STATUS_NOT_SUPPORTED
:
fatal_error
(
"'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.
\n
"
,
config_dir
);
case
STATUS_INVALID_IMAGE_FORMAT
:
fatal_error
(
"wineserver doesn't support the %s architecture
\n
"
,
cpu_names
[
client_cpu
]
);
default:
server_protocol_error
(
"init_first_thread failed with status %x
\n
"
,
ret
);
}
}
...
...
@@ -1530,88 +1631,25 @@ void server_init_process_done(void)
*
* Send an init thread request.
*/
size_t
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
void
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
{
static
const
char
*
cpu_names
[]
=
{
"x86"
,
"x86_64"
,
"PowerPC"
,
"ARM"
,
"ARM64"
};
const
char
*
arch
=
getenv
(
"WINEARCH"
);
int
ret
;
int
reply_pipe
[
2
];
struct
sigaction
sig_act
;
stack_t
ss
;
size_t
info_size
;
/* ignore SIGPIPE so that we get an EPIPE error instead */
sig_act
.
sa_handler
=
SIG_IGN
;
sig_act
.
sa_flags
=
0
;
sigemptyset
(
&
sig_act
.
sa_mask
);
sigaction
(
SIGPIPE
,
&
sig_act
,
NULL
);
ss
.
ss_sp
=
get_signal_stack
();
ss
.
ss_size
=
signal_stack_size
;
ss
.
ss_flags
=
0
;
sigaltstack
(
&
ss
,
NULL
);
/* create the server->client communication pipes */
if
(
server_pipe
(
reply_pipe
)
==
-
1
)
server_protocol_perror
(
"pipe"
);
if
(
server_pipe
(
ntdll_get_thread_data
()
->
wait_fd
)
==
-
1
)
server_protocol_perror
(
"pipe"
);
wine_server_send_fd
(
reply_pipe
[
1
]
);
wine_server_send_fd
(
ntdll_get_thread_data
()
->
wait_fd
[
1
]
);
ntdll_get_thread_data
()
->
reply_fd
=
reply_pipe
[
0
];
close
(
reply_pipe
[
1
]
);
int
reply_pipe
=
init_thread_pipe
();
SERVER_START_REQ
(
init_thread
)
{
req
->
unix_pid
=
getpid
();
req
->
unix_tid
=
get_unix_tid
();
req
->
teb
=
wine_server_client_ptr
(
NtCurrentTeb
()
);
req
->
entry
=
wine_server_client_ptr
(
entry_point
);
req
->
reply_fd
=
reply_pipe
[
1
];
req
->
wait_fd
=
ntdll_get_thread_data
()
->
wait_fd
[
1
];
req
->
debug_level
=
(
TRACE_ON
(
server
)
!=
0
);
req
->
cpu
=
client_cpu
;
ret
=
wine_server_call
(
req
);
req
->
unix_tid
=
get_unix_tid
();
req
->
teb
=
wine_server_client_ptr
(
NtCurrentTeb
()
);
req
->
entry
=
wine_server_client_ptr
(
entry_point
);
req
->
reply_fd
=
reply_pipe
;
req
->
wait_fd
=
ntdll_get_thread_data
()
->
wait_fd
[
1
];
wine_server_call
(
req
);
*
suspend
=
reply
->
suspend
;
NtCurrentTeb
()
->
ClientId
.
UniqueProcess
=
ULongToHandle
(
reply
->
pid
);
NtCurrentTeb
()
->
ClientId
.
UniqueThread
=
ULongToHandle
(
reply
->
tid
);
info_size
=
reply
->
info_size
;
server_start_time
=
reply
->
server_start
;
server_cpus
=
reply
->
all_cpus
;
*
suspend
=
reply
->
suspend
;
}
SERVER_END_REQ
;
#ifndef _WIN64
is_wow64
=
(
server_cpus
&
((
1
<<
CPU_x86_64
)
|
(
1
<<
CPU_ARM64
)))
!=
0
;
if
(
is_wow64
)
{
TEB64
*
teb64
=
(
TEB64
*
)((
char
*
)
NtCurrentTeb
()
-
teb_offset
);
NtCurrentTeb
()
->
GdiBatchCount
=
PtrToUlong
(
teb64
);
NtCurrentTeb
()
->
WowTebOffset
=
-
teb_offset
;
teb64
->
ClientId
.
UniqueProcess
=
PtrToUlong
(
NtCurrentTeb
()
->
ClientId
.
UniqueProcess
);
teb64
->
ClientId
.
UniqueThread
=
PtrToUlong
(
NtCurrentTeb
()
->
ClientId
.
UniqueThread
);
}
#endif
switch
(
ret
)
{
case
STATUS_SUCCESS
:
if
(
arch
)
{
if
(
!
strcmp
(
arch
,
"win32"
)
&&
(
is_win64
||
is_wow64
))
fatal_error
(
"WINEARCH set to win32 but '%s' is a 64-bit installation.
\n
"
,
config_dir
);
if
(
!
strcmp
(
arch
,
"win64"
)
&&
!
is_win64
&&
!
is_wow64
)
fatal_error
(
"WINEARCH set to win64 but '%s' is a 32-bit installation.
\n
"
,
config_dir
);
}
return
info_size
;
case
STATUS_INVALID_IMAGE_WIN_64
:
fatal_error
(
"'%s' is a 32-bit installation, it cannot support 64-bit applications.
\n
"
,
config_dir
);
case
STATUS_NOT_SUPPORTED
:
fatal_error
(
"'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.
\n
"
,
config_dir
);
case
STATUS_INVALID_IMAGE_FORMAT
:
fatal_error
(
"wineserver doesn't support the %s architecture
\n
"
,
cpu_names
[
client_cpu
]
);
default:
server_protocol_error
(
"init_thread failed with status %x
\n
"
,
ret
);
}
close
(
reply_pipe
);
init_teb64
(
NtCurrentTeb
()
);
}
...
...
dlls/ntdll/unix/unix_private.h
View file @
44699c32
...
...
@@ -157,9 +157,9 @@ extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *
apc_result_t
*
result
)
DECLSPEC_HIDDEN
;
extern
int
server_get_unix_fd
(
HANDLE
handle
,
unsigned
int
wanted_access
,
int
*
unix_fd
,
int
*
needs_close
,
enum
server_fd_type
*
type
,
unsigned
int
*
options
)
DECLSPEC_HIDDEN
;
extern
void
server_init_process
(
void
)
DECLSPEC_HIDDEN
;
extern
size_t
server_init_process
(
void
)
DECLSPEC_HIDDEN
;
extern
void
server_init_process_done
(
void
)
DECLSPEC_HIDDEN
;
extern
size_t
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
DECLSPEC_HIDDEN
;
extern
void
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
DECLSPEC_HIDDEN
;
extern
int
server_pipe
(
int
fd
[
2
]
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
DECLSPEC_HIDDEN
;
...
...
include/wine/server_protocol.h
View file @
44699c32
...
...
@@ -893,29 +893,47 @@ struct init_process_done_reply
struct
init_thread_request
struct
init_
first_
thread_request
{
struct
request_header
__header
;
int
unix_pid
;
int
unix_tid
;
int
debug_level
;
client_ptr_t
teb
;
client_ptr_t
entry
;
client_ptr_t
peb
;
int
reply_fd
;
int
wait_fd
;
client_cpu_t
cpu
;
char
__pad_52
[
4
];
};
struct
init_thread_reply
struct
init_
first_
thread_reply
{
struct
reply_header
__header
;
process_id_t
pid
;
thread_id_t
tid
;
timeout_t
server_start
;
data_size_t
info_size
;
int
version
;
unsigned
int
all_cpus
;
};
struct
init_thread_request
{
struct
request_header
__header
;
int
unix_tid
;
int
reply_fd
;
int
wait_fd
;
client_ptr_t
teb
;
client_ptr_t
entry
;
};
struct
init_thread_reply
{
struct
reply_header
__header
;
process_id_t
pid
;
thread_id_t
tid
;
int
suspend
;
char
__pad_20
[
4
];
};
...
...
@@ -5373,6 +5391,7 @@ enum request
REQ_new_thread
,
REQ_get_startup_info
,
REQ_init_process_done
,
REQ_init_first_thread
,
REQ_init_thread
,
REQ_terminate_process
,
REQ_terminate_thread
,
...
...
@@ -5655,6 +5674,7 @@ union generic_request
struct
new_thread_request
new_thread_request
;
struct
get_startup_info_request
get_startup_info_request
;
struct
init_process_done_request
init_process_done_request
;
struct
init_first_thread_request
init_first_thread_request
;
struct
init_thread_request
init_thread_request
;
struct
terminate_process_request
terminate_process_request
;
struct
terminate_thread_request
terminate_thread_request
;
...
...
@@ -5935,6 +5955,7 @@ union generic_reply
struct
new_thread_reply
new_thread_reply
;
struct
get_startup_info_reply
get_startup_info_reply
;
struct
init_process_done_reply
init_process_done_reply
;
struct
init_first_thread_reply
init_first_thread_reply
;
struct
init_thread_reply
init_thread_reply
;
struct
terminate_process_reply
terminate_process_reply
;
struct
terminate_thread_reply
terminate_thread_reply
;
...
...
@@ -6208,7 +6229,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 66
2
#define SERVER_PROTOCOL_VERSION 66
3
/* ### protocol_version end ### */
...
...
server/process.c
View file @
44699c32
...
...
@@ -607,10 +607,9 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
return
NULL
;
}
/*
initialize the current process and fill in the request
*/
data_size_t
init_process
(
struct
thread
*
thread
)
/*
get the process data size
*/
data_size_t
get_process_startup_info_size
(
struct
process
*
process
)
{
struct
process
*
process
=
thread
->
process
;
struct
startup_info
*
info
=
process
->
startup_info
;
if
(
!
info
)
return
0
;
...
...
server/process.h
View file @
44699c32
...
...
@@ -108,7 +108,7 @@ extern void *get_ptid_entry( unsigned int id );
extern
struct
process
*
create_process
(
int
fd
,
struct
process
*
parent
,
int
inherit_all
,
const
startup_info_t
*
info
,
const
struct
security_descriptor
*
sd
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
,
struct
token
*
token
);
extern
data_size_t
init_process
(
struct
thread
*
thread
);
extern
data_size_t
get_process_startup_info_size
(
struct
process
*
process
);
extern
struct
thread
*
get_process_first_thread
(
struct
process
*
process
);
extern
struct
process
*
get_process_from_id
(
process_id_t
id
);
extern
struct
process
*
get_process_from_handle
(
obj_handle_t
handle
,
unsigned
int
access
);
...
...
server/protocol.def
View file @
44699c32
...
...
@@ -870,13 +870,13 @@ typedef struct
@END
/* Initialize
a thread; called from the child after fork()/clone()
*/
@REQ(init_thread)
int unix_pid; /* Unix pid of new
thread
*/
/* Initialize
the first thread of a new process
*/
@REQ(init_
first_
thread)
int unix_pid; /* Unix pid of new
process
*/
int unix_tid; /* Unix tid of new thread */
int debug_level; /* new debug level */
client_ptr_t teb; /* TEB of new thread (in
thread
address space) */
client_ptr_t
entry; /* entry point or PEB if initial thread (in thread
address space) */
client_ptr_t teb; /* TEB of new thread (in
process
address space) */
client_ptr_t
peb; /* PEB of new process (in process
address space) */
int reply_fd; /* fd for reply pipe */
int wait_fd; /* fd for blocking calls pipe */
client_cpu_t cpu; /* CPU that this thread is running on */
...
...
@@ -885,8 +885,20 @@ typedef struct
thread_id_t tid; /* thread id of the new thread */
timeout_t server_start; /* server start time */
data_size_t info_size; /* total size of startup info */
int version; /* protocol version */
unsigned int all_cpus; /* bitset of supported CPUs */
@END
/* Initialize a new thread; called from the child after pthread_create() */
@REQ(init_thread)
int unix_tid; /* Unix tid of new thread */
int reply_fd; /* fd for reply pipe */
int wait_fd; /* fd for blocking calls pipe */
client_ptr_t teb; /* TEB of new thread (in thread address space) */
client_ptr_t entry; /* entry point (in thread address space) */
@REPLY
process_id_t pid; /* process id of the new thread's process */
thread_id_t tid; /* thread id of the new thread */
int suspend; /* is thread suspended? */
@END
...
...
server/request.h
View file @
44699c32
...
...
@@ -125,6 +125,7 @@ DECL_HANDLER(get_new_process_info);
DECL_HANDLER
(
new_thread
);
DECL_HANDLER
(
get_startup_info
);
DECL_HANDLER
(
init_process_done
);
DECL_HANDLER
(
init_first_thread
);
DECL_HANDLER
(
init_thread
);
DECL_HANDLER
(
terminate_process
);
DECL_HANDLER
(
terminate_thread
);
...
...
@@ -406,6 +407,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_new_thread
,
(
req_handler
)
req_get_startup_info
,
(
req_handler
)
req_init_process_done
,
(
req_handler
)
req_init_first_thread
,
(
req_handler
)
req_init_thread
,
(
req_handler
)
req_terminate_process
,
(
req_handler
)
req_terminate_thread
,
...
...
@@ -748,23 +750,31 @@ C_ASSERT( FIELD_OFFSET(struct init_process_done_request, entry) == 32 );
C_ASSERT
(
sizeof
(
struct
init_process_done_request
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_process_done_reply
,
suspend
)
==
8
);
C_ASSERT
(
sizeof
(
struct
init_process_done_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
unix_pid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
unix_tid
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
debug_level
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
unix_pid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
unix_tid
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
debug_level
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
teb
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
peb
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
reply_fd
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
wait_fd
)
==
44
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_request
,
cpu
)
==
48
);
C_ASSERT
(
sizeof
(
struct
init_first_thread_request
)
==
56
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_reply
,
pid
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_reply
,
tid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_reply
,
server_start
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_reply
,
info_size
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_first_thread_reply
,
all_cpus
)
==
28
);
C_ASSERT
(
sizeof
(
struct
init_first_thread_reply
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
unix_tid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
reply_fd
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
wait_fd
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
teb
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
entry
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
reply_fd
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
wait_fd
)
==
44
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_request
,
cpu
)
==
48
);
C_ASSERT
(
sizeof
(
struct
init_thread_request
)
==
56
);
C_ASSERT
(
sizeof
(
struct
init_thread_request
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
pid
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
tid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
server_start
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
info_size
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
version
)
==
28
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
all_cpus
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
suspend
)
==
36
);
C_ASSERT
(
sizeof
(
struct
init_thread_reply
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
suspend
)
==
16
);
C_ASSERT
(
sizeof
(
struct
init_thread_reply
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
terminate_process_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
terminate_process_request
,
exit_code
)
==
16
);
C_ASSERT
(
sizeof
(
struct
terminate_process_request
)
==
24
);
...
...
server/thread.c
View file @
44699c32
...
...
@@ -1384,24 +1384,20 @@ done:
release_object
(
process
);
}
/* initialize a new thread */
DECL_HANDLER
(
init_thread
)
static
int
init_thread
(
struct
thread
*
thread
,
int
reply_fd
,
int
wait_fd
)
{
struct
process
*
process
=
current
->
process
;
int
wait_fd
,
reply_fd
;
if
((
reply_fd
=
thread_get_inflight_fd
(
current
,
req
->
reply_fd
))
==
-
1
)
if
((
reply_fd
=
thread_get_inflight_fd
(
thread
,
reply_fd
))
==
-
1
)
{
set_error
(
STATUS_TOO_MANY_OPENED_FILES
);
return
;
return
0
;
}
if
((
wait_fd
=
thread_get_inflight_fd
(
current
,
req
->
wait_fd
))
==
-
1
)
if
((
wait_fd
=
thread_get_inflight_fd
(
thread
,
wait_fd
))
==
-
1
)
{
set_error
(
STATUS_TOO_MANY_OPENED_FILES
);
goto
error
;
}
if
(
current
->
reply_fd
)
/* already initialised */
if
(
thread
->
reply_fd
)
/* already initialised */
{
set_error
(
STATUS_INVALID_PARAMETER
);
goto
error
;
...
...
@@ -1409,59 +1405,74 @@ DECL_HANDLER(init_thread)
if
(
fcntl
(
reply_fd
,
F_SETFL
,
O_NONBLOCK
)
==
-
1
)
goto
error
;
current
->
reply_fd
=
create_anonymous_fd
(
&
thread_fd_ops
,
reply_fd
,
&
current
->
obj
,
0
);
current
->
wait_fd
=
create_anonymous_fd
(
&
thread_fd_ops
,
wait_fd
,
&
current
->
obj
,
0
);
if
(
!
current
->
reply_fd
||
!
current
->
wait_fd
)
return
;
thread
->
reply_fd
=
create_anonymous_fd
(
&
thread_fd_ops
,
reply_fd
,
&
thread
->
obj
,
0
);
thread
->
wait_fd
=
create_anonymous_fd
(
&
thread_fd_ops
,
wait_fd
,
&
thread
->
obj
,
0
);
return
thread
->
reply_fd
&&
thread
->
wait_fd
;
if
(
!
is_valid_address
(
req
->
teb
))
error
:
if
(
reply_fd
!=
-
1
)
close
(
reply_fd
);
if
(
wait_fd
!=
-
1
)
close
(
wait_fd
);
return
0
;
}
/* initialize the first thread of a new process */
DECL_HANDLER
(
init_first_thread
)
{
struct
process
*
process
=
current
->
process
;
if
(
!
init_thread
(
current
,
req
->
reply_fd
,
req
->
wait_fd
))
return
;
if
(
!
is_valid_address
(
req
->
teb
)
||
!
is_valid_address
(
req
->
peb
))
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
current
->
unix_pid
=
req
->
unix_pid
;
if
(
!
is_cpu_supported
(
req
->
cpu
))
return
;
current
->
unix_pid
=
process
->
unix_pid
=
req
->
unix_pid
;
current
->
unix_tid
=
req
->
unix_tid
;
current
->
teb
=
req
->
teb
;
current
->
entry_point
=
process
->
peb
?
req
->
entry
:
0
;
process
->
peb
=
req
->
peb
;
process
->
cpu
=
req
->
cpu
;
if
(
!
process
->
peb
)
/* first thread, initialize the process too */
{
if
(
!
is_cpu_supported
(
req
->
cpu
))
return
;
process
->
unix_pid
=
current
->
unix_pid
;
process
->
peb
=
req
->
entry
;
process
->
cpu
=
req
->
cpu
;
reply
->
info_size
=
init_process
(
current
);
if
(
!
process
->
parent_id
)
process
->
affinity
=
current
->
affinity
=
get_thread_affinity
(
current
);
else
set_thread_affinity
(
current
,
current
->
affinity
);
}
if
(
!
process
->
parent_id
)
process
->
affinity
=
current
->
affinity
=
get_thread_affinity
(
current
);
else
{
if
(
req
->
cpu
!=
process
->
cpu
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
process
->
unix_pid
!=
current
->
unix_pid
)
process
->
unix_pid
=
-
1
;
/* can happen with linuxthreads */
init_thread_context
(
current
);
generate_debug_event
(
current
,
DbgCreateThreadStateChange
,
&
req
->
entry
);
set_thread_affinity
(
current
,
current
->
affinity
);
}
debug_level
=
max
(
debug_level
,
req
->
debug_level
);
reply
->
pid
=
get_process_id
(
process
);
reply
->
tid
=
get_thread_id
(
current
);
reply
->
version
=
SERVER_PROTOCOL_VERSION
;
reply
->
pid
=
get_process_id
(
process
);
reply
->
tid
=
get_thread_id
(
current
);
reply
->
info_size
=
get_process_startup_info_size
(
process
)
;
reply
->
server_start
=
server_start_time
;
reply
->
all_cpus
=
supported_cpus
&
get_prefix_cpu_mask
();
reply
->
suspend
=
(
current
->
suspend
||
process
->
suspend
||
current
->
context
!=
NULL
);
return
;
}
error
:
if
(
reply_fd
!=
-
1
)
close
(
reply_fd
);
if
(
wait_fd
!=
-
1
)
close
(
wait_fd
);
/* initialize a new thread */
DECL_HANDLER
(
init_thread
)
{
if
(
!
init_thread
(
current
,
req
->
reply_fd
,
req
->
wait_fd
))
return
;
if
(
!
is_valid_address
(
req
->
teb
))
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
current
->
unix_pid
=
current
->
process
->
unix_pid
;
current
->
unix_tid
=
req
->
unix_tid
;
current
->
teb
=
req
->
teb
;
current
->
entry_point
=
req
->
entry
;
init_thread_context
(
current
);
generate_debug_event
(
current
,
DbgCreateThreadStateChange
,
&
req
->
entry
);
set_thread_affinity
(
current
,
current
->
affinity
);
reply
->
pid
=
get_process_id
(
current
->
process
);
reply
->
tid
=
get_thread_id
(
current
);
reply
->
suspend
=
(
current
->
suspend
||
current
->
process
->
suspend
||
current
->
context
!=
NULL
);
}
/* terminate a thread */
...
...
server/trace.c
View file @
44699c32
...
...
@@ -1392,26 +1392,40 @@ static void dump_init_process_done_reply( const struct init_process_done_reply *
fprintf
(
stderr
,
" suspend=%d"
,
req
->
suspend
);
}
static
void
dump_init_
thread_request
(
const
struct
ini
t_thread_request
*
req
)
static
void
dump_init_
first_thread_request
(
const
struct
init_firs
t_thread_request
*
req
)
{
fprintf
(
stderr
,
" unix_pid=%d"
,
req
->
unix_pid
);
fprintf
(
stderr
,
", unix_tid=%d"
,
req
->
unix_tid
);
fprintf
(
stderr
,
", debug_level=%d"
,
req
->
debug_level
);
dump_uint64
(
", teb="
,
&
req
->
teb
);
dump_uint64
(
",
entry="
,
&
req
->
entry
);
dump_uint64
(
",
peb="
,
&
req
->
peb
);
fprintf
(
stderr
,
", reply_fd=%d"
,
req
->
reply_fd
);
fprintf
(
stderr
,
", wait_fd=%d"
,
req
->
wait_fd
);
dump_client_cpu
(
", cpu="
,
&
req
->
cpu
);
}
static
void
dump_init_
thread_reply
(
const
struct
ini
t_thread_reply
*
req
)
static
void
dump_init_
first_thread_reply
(
const
struct
init_firs
t_thread_reply
*
req
)
{
fprintf
(
stderr
,
" pid=%04x"
,
req
->
pid
);
fprintf
(
stderr
,
", tid=%04x"
,
req
->
tid
);
dump_timeout
(
", server_start="
,
&
req
->
server_start
);
fprintf
(
stderr
,
", info_size=%u"
,
req
->
info_size
);
fprintf
(
stderr
,
", version=%d"
,
req
->
version
);
fprintf
(
stderr
,
", all_cpus=%08x"
,
req
->
all_cpus
);
}
static
void
dump_init_thread_request
(
const
struct
init_thread_request
*
req
)
{
fprintf
(
stderr
,
" unix_tid=%d"
,
req
->
unix_tid
);
fprintf
(
stderr
,
", reply_fd=%d"
,
req
->
reply_fd
);
fprintf
(
stderr
,
", wait_fd=%d"
,
req
->
wait_fd
);
dump_uint64
(
", teb="
,
&
req
->
teb
);
dump_uint64
(
", entry="
,
&
req
->
entry
);
}
static
void
dump_init_thread_reply
(
const
struct
init_thread_reply
*
req
)
{
fprintf
(
stderr
,
" pid=%04x"
,
req
->
pid
);
fprintf
(
stderr
,
", tid=%04x"
,
req
->
tid
);
fprintf
(
stderr
,
", suspend=%d"
,
req
->
suspend
);
}
...
...
@@ -4407,6 +4421,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_new_thread_request
,
(
dump_func
)
dump_get_startup_info_request
,
(
dump_func
)
dump_init_process_done_request
,
(
dump_func
)
dump_init_first_thread_request
,
(
dump_func
)
dump_init_thread_request
,
(
dump_func
)
dump_terminate_process_request
,
(
dump_func
)
dump_terminate_thread_request
,
...
...
@@ -4685,6 +4700,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_new_thread_reply
,
(
dump_func
)
dump_get_startup_info_reply
,
(
dump_func
)
dump_init_process_done_reply
,
(
dump_func
)
dump_init_first_thread_reply
,
(
dump_func
)
dump_init_thread_reply
,
(
dump_func
)
dump_terminate_process_reply
,
(
dump_func
)
dump_terminate_thread_reply
,
...
...
@@ -4963,6 +4979,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"new_thread"
,
"get_startup_info"
,
"init_process_done"
,
"init_first_thread"
,
"init_thread"
,
"terminate_process"
,
"terminate_thread"
,
...
...
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