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
e9936d96
Commit
e9936d96
authored
Jan 26, 2001
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed wait_process and wait_debug_event requests to never block;
waiting is always done through WaitForSingleObject().
parent
819bff4d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
190 additions
and
219 deletions
+190
-219
debugger.c
dlls/kernel/debugger.c
+81
-71
server.h
include/server.h
+9
-8
process.c
scheduler/process.c
+22
-14
debugger.c
server/debugger.c
+25
-57
process.c
server/process.c
+36
-57
request.h
server/request.h
+2
-2
trace.c
server/trace.c
+15
-10
No files found.
dlls/kernel/debugger.c
View file @
e9936d96
...
@@ -31,82 +31,92 @@ BOOL WINAPI WaitForDebugEvent(
...
@@ -31,82 +31,92 @@ BOOL WINAPI WaitForDebugEvent(
DWORD
timeout
/* Number of milliseconds to wait for event. */
)
DWORD
timeout
/* Number of milliseconds to wait for event. */
)
{
{
BOOL
ret
;
BOOL
ret
;
SERVER_START_REQ
DWORD
res
;
for
(;;)
{
{
debug_event_t
*
data
;
HANDLE
wait
=
0
;
struct
wait_debug_event_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
sizeof
(
*
data
)
);
SERVER_START_REQ
{
debug_event_t
*
data
;
struct
wait_debug_event_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
sizeof
(
*
data
)
);
req
->
timeout
=
timeout
;
req
->
get_handle
=
(
timeout
!=
0
)
;
if
(
!
(
ret
=
!
server_call
(
REQ_WAIT_DEBUG_EVENT
)))
goto
done
;
if
(
!
(
ret
=
!
server_call
(
REQ_WAIT_DEBUG_EVENT
)))
goto
done
;
if
(
!
server_data_size
(
req
))
/* timeout */
if
(
!
server_data_size
(
req
))
/* timeout */
{
{
SetLastError
(
ERROR_SEM_TIMEOUT
);
wait
=
req
->
wait
;
ret
=
FALSE
;
ret
=
FALSE
;
goto
done
;
goto
done
;
}
data
=
server_data_ptr
(
req
);
event
->
dwDebugEventCode
=
data
->
code
;
event
->
dwProcessId
=
(
DWORD
)
req
->
pid
;
event
->
dwThreadId
=
(
DWORD
)
req
->
tid
;
switch
(
data
->
code
)
{
case
EXCEPTION_DEBUG_EVENT
:
event
->
u
.
Exception
.
ExceptionRecord
=
data
->
info
.
exception
.
record
;
event
->
u
.
Exception
.
dwFirstChance
=
data
->
info
.
exception
.
first
;
break
;
case
CREATE_THREAD_DEBUG_EVENT
:
event
->
u
.
CreateThread
.
hThread
=
data
->
info
.
create_thread
.
handle
;
event
->
u
.
CreateThread
.
lpThreadLocalBase
=
data
->
info
.
create_thread
.
teb
;
event
->
u
.
CreateThread
.
lpStartAddress
=
data
->
info
.
create_thread
.
start
;
break
;
case
CREATE_PROCESS_DEBUG_EVENT
:
event
->
u
.
CreateProcessInfo
.
hFile
=
data
->
info
.
create_process
.
file
;
event
->
u
.
CreateProcessInfo
.
hProcess
=
data
->
info
.
create_process
.
process
;
event
->
u
.
CreateProcessInfo
.
hThread
=
data
->
info
.
create_process
.
thread
;
event
->
u
.
CreateProcessInfo
.
lpBaseOfImage
=
data
->
info
.
create_process
.
base
;
event
->
u
.
CreateProcessInfo
.
dwDebugInfoFileOffset
=
data
->
info
.
create_process
.
dbg_offset
;
event
->
u
.
CreateProcessInfo
.
nDebugInfoSize
=
data
->
info
.
create_process
.
dbg_size
;
event
->
u
.
CreateProcessInfo
.
lpThreadLocalBase
=
data
->
info
.
create_process
.
teb
;
event
->
u
.
CreateProcessInfo
.
lpStartAddress
=
data
->
info
.
create_process
.
start
;
event
->
u
.
CreateProcessInfo
.
lpImageName
=
data
->
info
.
create_process
.
name
;
event
->
u
.
CreateProcessInfo
.
fUnicode
=
data
->
info
.
create_process
.
unicode
;
if
(
data
->
info
.
create_process
.
file
==
-
1
)
event
->
u
.
CreateProcessInfo
.
hFile
=
0
;
break
;
case
EXIT_THREAD_DEBUG_EVENT
:
event
->
u
.
ExitThread
.
dwExitCode
=
data
->
info
.
exit
.
exit_code
;
break
;
case
EXIT_PROCESS_DEBUG_EVENT
:
event
->
u
.
ExitProcess
.
dwExitCode
=
data
->
info
.
exit
.
exit_code
;
break
;
case
LOAD_DLL_DEBUG_EVENT
:
event
->
u
.
LoadDll
.
hFile
=
data
->
info
.
load_dll
.
handle
;
event
->
u
.
LoadDll
.
lpBaseOfDll
=
data
->
info
.
load_dll
.
base
;
event
->
u
.
LoadDll
.
dwDebugInfoFileOffset
=
data
->
info
.
load_dll
.
dbg_offset
;
event
->
u
.
LoadDll
.
nDebugInfoSize
=
data
->
info
.
load_dll
.
dbg_size
;
event
->
u
.
LoadDll
.
lpImageName
=
data
->
info
.
load_dll
.
name
;
event
->
u
.
LoadDll
.
fUnicode
=
data
->
info
.
load_dll
.
unicode
;
if
(
data
->
info
.
load_dll
.
handle
==
-
1
)
event
->
u
.
LoadDll
.
hFile
=
0
;
break
;
case
UNLOAD_DLL_DEBUG_EVENT
:
event
->
u
.
UnloadDll
.
lpBaseOfDll
=
data
->
info
.
unload_dll
.
base
;
break
;
case
OUTPUT_DEBUG_STRING_EVENT
:
event
->
u
.
DebugString
.
lpDebugStringData
=
data
->
info
.
output_string
.
string
;
event
->
u
.
DebugString
.
fUnicode
=
data
->
info
.
output_string
.
unicode
;
event
->
u
.
DebugString
.
nDebugStringLength
=
data
->
info
.
output_string
.
length
;
break
;
case
RIP_EVENT
:
event
->
u
.
RipInfo
.
dwError
=
data
->
info
.
rip_info
.
error
;
event
->
u
.
RipInfo
.
dwType
=
data
->
info
.
rip_info
.
type
;
break
;
}
done:
}
}
data
=
server_data_ptr
(
req
);
SERVER_END_REQ
;
event
->
dwDebugEventCode
=
data
->
code
;
if
(
ret
)
return
TRUE
;
event
->
dwProcessId
=
(
DWORD
)
req
->
pid
;
if
(
!
wait
)
break
;
event
->
dwThreadId
=
(
DWORD
)
req
->
tid
;
res
=
WaitForSingleObject
(
wait
,
timeout
);
switch
(
data
->
code
)
CloseHandle
(
wait
);
{
if
(
res
!=
STATUS_WAIT_0
)
break
;
case
EXCEPTION_DEBUG_EVENT
:
event
->
u
.
Exception
.
ExceptionRecord
=
data
->
info
.
exception
.
record
;
event
->
u
.
Exception
.
dwFirstChance
=
data
->
info
.
exception
.
first
;
break
;
case
CREATE_THREAD_DEBUG_EVENT
:
event
->
u
.
CreateThread
.
hThread
=
data
->
info
.
create_thread
.
handle
;
event
->
u
.
CreateThread
.
lpThreadLocalBase
=
data
->
info
.
create_thread
.
teb
;
event
->
u
.
CreateThread
.
lpStartAddress
=
data
->
info
.
create_thread
.
start
;
break
;
case
CREATE_PROCESS_DEBUG_EVENT
:
event
->
u
.
CreateProcessInfo
.
hFile
=
data
->
info
.
create_process
.
file
;
event
->
u
.
CreateProcessInfo
.
hProcess
=
data
->
info
.
create_process
.
process
;
event
->
u
.
CreateProcessInfo
.
hThread
=
data
->
info
.
create_process
.
thread
;
event
->
u
.
CreateProcessInfo
.
lpBaseOfImage
=
data
->
info
.
create_process
.
base
;
event
->
u
.
CreateProcessInfo
.
dwDebugInfoFileOffset
=
data
->
info
.
create_process
.
dbg_offset
;
event
->
u
.
CreateProcessInfo
.
nDebugInfoSize
=
data
->
info
.
create_process
.
dbg_size
;
event
->
u
.
CreateProcessInfo
.
lpThreadLocalBase
=
data
->
info
.
create_process
.
teb
;
event
->
u
.
CreateProcessInfo
.
lpStartAddress
=
data
->
info
.
create_process
.
start
;
event
->
u
.
CreateProcessInfo
.
lpImageName
=
data
->
info
.
create_process
.
name
;
event
->
u
.
CreateProcessInfo
.
fUnicode
=
data
->
info
.
create_process
.
unicode
;
if
(
data
->
info
.
create_process
.
file
==
-
1
)
event
->
u
.
CreateProcessInfo
.
hFile
=
0
;
break
;
case
EXIT_THREAD_DEBUG_EVENT
:
event
->
u
.
ExitThread
.
dwExitCode
=
data
->
info
.
exit
.
exit_code
;
break
;
case
EXIT_PROCESS_DEBUG_EVENT
:
event
->
u
.
ExitProcess
.
dwExitCode
=
data
->
info
.
exit
.
exit_code
;
break
;
case
LOAD_DLL_DEBUG_EVENT
:
event
->
u
.
LoadDll
.
hFile
=
data
->
info
.
load_dll
.
handle
;
event
->
u
.
LoadDll
.
lpBaseOfDll
=
data
->
info
.
load_dll
.
base
;
event
->
u
.
LoadDll
.
dwDebugInfoFileOffset
=
data
->
info
.
load_dll
.
dbg_offset
;
event
->
u
.
LoadDll
.
nDebugInfoSize
=
data
->
info
.
load_dll
.
dbg_size
;
event
->
u
.
LoadDll
.
lpImageName
=
data
->
info
.
load_dll
.
name
;
event
->
u
.
LoadDll
.
fUnicode
=
data
->
info
.
load_dll
.
unicode
;
if
(
data
->
info
.
load_dll
.
handle
==
-
1
)
event
->
u
.
LoadDll
.
hFile
=
0
;
break
;
case
UNLOAD_DLL_DEBUG_EVENT
:
event
->
u
.
UnloadDll
.
lpBaseOfDll
=
data
->
info
.
unload_dll
.
base
;
break
;
case
OUTPUT_DEBUG_STRING_EVENT
:
event
->
u
.
DebugString
.
lpDebugStringData
=
data
->
info
.
output_string
.
string
;
event
->
u
.
DebugString
.
fUnicode
=
data
->
info
.
output_string
.
unicode
;
event
->
u
.
DebugString
.
nDebugStringLength
=
data
->
info
.
output_string
.
length
;
break
;
case
RIP_EVENT
:
event
->
u
.
RipInfo
.
dwError
=
data
->
info
.
rip_info
.
error
;
event
->
u
.
RipInfo
.
dwType
=
data
->
info
.
rip_info
.
type
;
break
;
default:
server_protocol_error
(
"WaitForDebugEvent: bad code %d
\n
"
,
data
->
code
);
}
done:
}
}
S
ERVER_END_REQ
;
S
etLastError
(
ERROR_SEM_TIMEOUT
)
;
return
ret
;
return
FALSE
;
}
}
...
...
include/server.h
View file @
e9936d96
...
@@ -131,18 +131,18 @@ struct new_process_request
...
@@ -131,18 +131,18 @@ struct new_process_request
IN
handle_t
hstdout
;
/* handle for stdout */
IN
handle_t
hstdout
;
/* handle for stdout */
IN
handle_t
hstderr
;
/* handle for stderr */
IN
handle_t
hstderr
;
/* handle for stderr */
IN
int
cmd_show
;
/* main window show mode */
IN
int
cmd_show
;
/* main window show mode */
OUT
handle_t
info
;
/* new process info handle */
IN
VARARG
(
filename
,
string
);
/* file name of main exe */
IN
VARARG
(
filename
,
string
);
/* file name of main exe */
};
};
/*
Wait for the new process to start
*/
/*
Retrieve information about a newly started process
*/
struct
wait_process
_request
struct
get_new_process_info
_request
{
{
REQUEST_HEADER
;
/* request header */
REQUEST_HEADER
;
/* request header */
IN
handle_t
info
;
/* info handle returned from new_process_request */
IN
int
pinherit
;
/* process handle inherit flag */
IN
int
pinherit
;
/* process handle inherit flag */
IN
int
tinherit
;
/* thread handle inherit flag */
IN
int
tinherit
;
/* thread handle inherit flag */
IN
int
timeout
;
/* wait timeout */
IN
int
cancel
;
/* cancel the process creation? */
OUT
void
*
pid
;
/* process id */
OUT
void
*
pid
;
/* process id */
OUT
handle_t
phandle
;
/* process handle (in the current process) */
OUT
handle_t
phandle
;
/* process handle (in the current process) */
OUT
void
*
tid
;
/* thread id */
OUT
void
*
tid
;
/* thread id */
...
@@ -930,9 +930,10 @@ struct next_module_request
...
@@ -930,9 +930,10 @@ struct next_module_request
struct
wait_debug_event_request
struct
wait_debug_event_request
{
{
REQUEST_HEADER
;
/* request header */
REQUEST_HEADER
;
/* request header */
IN
int
timeout
;
/* timeout in ms
*/
IN
int
get_handle
;
/* should we alloc a handle for waiting?
*/
OUT
void
*
pid
;
/* process id */
OUT
void
*
pid
;
/* process id */
OUT
void
*
tid
;
/* thread id */
OUT
void
*
tid
;
/* thread id */
OUT
handle_t
wait
;
/* wait handle if no event ready */
OUT
VARARG
(
event
,
debug_event
);
/* debug event data */
OUT
VARARG
(
event
,
debug_event
);
/* debug event data */
};
};
...
@@ -1356,7 +1357,7 @@ struct async_result_request
...
@@ -1356,7 +1357,7 @@ struct async_result_request
enum
request
enum
request
{
{
REQ_NEW_PROCESS
,
REQ_NEW_PROCESS
,
REQ_
WAIT_PROCESS
,
REQ_
GET_NEW_PROCESS_INFO
,
REQ_NEW_THREAD
,
REQ_NEW_THREAD
,
REQ_BOOT_DONE
,
REQ_BOOT_DONE
,
REQ_INIT_PROCESS
,
REQ_INIT_PROCESS
,
...
@@ -1471,7 +1472,7 @@ union generic_request
...
@@ -1471,7 +1472,7 @@ union generic_request
struct
request_max_size
max_size
;
struct
request_max_size
max_size
;
struct
request_header
header
;
struct
request_header
header
;
struct
new_process_request
new_process
;
struct
new_process_request
new_process
;
struct
wait_process_request
wait_process
;
struct
get_new_process_info_request
get_new_process_info
;
struct
new_thread_request
new_thread
;
struct
new_thread_request
new_thread
;
struct
boot_done_request
boot_done
;
struct
boot_done_request
boot_done
;
struct
init_process_request
init_process
;
struct
init_process_request
init_process
;
...
@@ -1580,7 +1581,7 @@ union generic_request
...
@@ -1580,7 +1581,7 @@ union generic_request
struct
async_result_request
async_result
;
struct
async_result_request
async_result
;
};
};
#define SERVER_PROTOCOL_VERSION 3
4
#define SERVER_PROTOCOL_VERSION 3
5
/* ### make_requests end ### */
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
/* Everything above this line is generated automatically by tools/make_requests */
...
...
scheduler/process.c
View file @
e9936d96
...
@@ -743,6 +743,7 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
...
@@ -743,6 +743,7 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
const
char
*
unixdir
=
NULL
;
const
char
*
unixdir
=
NULL
;
DOS_FULL_NAME
full_dir
,
full_name
;
DOS_FULL_NAME
full_dir
,
full_name
;
HANDLE
load_done_evt
=
0
;
HANDLE
load_done_evt
=
0
;
HANDLE
process_info
;
info
->
hThread
=
info
->
hProcess
=
0
;
info
->
hThread
=
info
->
hProcess
=
0
;
...
@@ -797,6 +798,7 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
...
@@ -797,6 +798,7 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
lstrcpynA
(
server_data_ptr
(
req
),
filename
,
MAX_PATH
);
lstrcpynA
(
server_data_ptr
(
req
),
filename
,
MAX_PATH
);
}
}
ret
=
!
server_call
(
REQ_NEW_PROCESS
);
ret
=
!
server_call
(
REQ_NEW_PROCESS
);
process_info
=
req
->
info
;
}
}
SERVER_END_REQ
;
SERVER_END_REQ
;
if
(
!
ret
)
return
FALSE
;
if
(
!
ret
)
return
FALSE
;
...
@@ -805,24 +807,30 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
...
@@ -805,24 +807,30 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
pid
=
fork_and_exec
(
unixfilename
,
cmd_line
,
env
,
unixdir
);
pid
=
fork_and_exec
(
unixfilename
,
cmd_line
,
env
,
unixdir
);
SERVER_START_REQ
/* wait for the new process info to be ready */
ret
=
FALSE
;
if
((
pid
!=
-
1
)
&&
(
WaitForSingleObject
(
process_info
,
2000
)
==
STATUS_WAIT_0
))
{
{
struct
wait_process_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
0
);
SERVER_START_REQ
req
->
cancel
=
(
pid
==
-
1
);
req
->
pinherit
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
);
req
->
tinherit
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
);
req
->
timeout
=
2000
;
if
((
ret
=
!
server_call
(
REQ_WAIT_PROCESS
))
&&
(
pid
!=
-
1
))
{
{
info
->
dwProcessId
=
(
DWORD
)
req
->
pid
;
struct
get_new_process_info_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
0
);
info
->
dwThreadId
=
(
DWORD
)
req
->
tid
;
req
->
info
=
process_info
;
info
->
hProcess
=
req
->
phandle
;
req
->
pinherit
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
);
info
->
hThread
=
req
->
thandle
;
req
->
tinherit
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
);
load_done_evt
=
req
->
event
;
if
((
ret
=
!
server_call
(
REQ_GET_NEW_PROCESS_INFO
)))
{
info
->
dwProcessId
=
(
DWORD
)
req
->
pid
;
info
->
dwThreadId
=
(
DWORD
)
req
->
tid
;
info
->
hProcess
=
req
->
phandle
;
info
->
hThread
=
req
->
thandle
;
load_done_evt
=
req
->
event
;
}
}
}
SERVER_END_REQ
;
}
}
SERVER_END_REQ
;
CloseHandle
(
process_info
)
;
if
(
!
ret
||
(
pid
==
-
1
)
)
goto
error
;
if
(
!
ret
)
goto
error
;
/* Wait until process is initialized (or initialization failed) */
/* Wait until process is initialized (or initialization failed) */
if
(
load_done_evt
)
if
(
load_done_evt
)
...
...
server/debugger.c
View file @
e9936d96
...
@@ -241,37 +241,6 @@ static struct debug_event *find_event_to_send( struct debug_ctx *debug_ctx )
...
@@ -241,37 +241,6 @@ static struct debug_event *find_event_to_send( struct debug_ctx *debug_ctx )
return
event
;
return
event
;
}
}
/* build a reply for the wait_debug_event request */
static
void
build_wait_debug_reply
(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
)
{
struct
wait_debug_event_request
*
req
=
get_req_ptr
(
thread
);
if
(
obj
)
{
struct
debug_ctx
*
debug_ctx
=
(
struct
debug_ctx
*
)
obj
;
struct
debug_event
*
event
=
find_event_to_send
(
debug_ctx
);
size_t
size
=
get_req_data_size
(
req
);
/* the object that woke us has to be our debug context */
assert
(
obj
->
ops
==
&
debug_ctx_ops
);
assert
(
event
);
event
->
state
=
EVENT_SENT
;
event
->
sender
->
debug_event
=
event
;
req
->
pid
=
event
->
sender
->
process
;
req
->
tid
=
event
->
sender
;
if
(
size
>
sizeof
(
debug_event_t
))
size
=
sizeof
(
debug_event_t
);
memcpy
(
get_req_data
(
req
),
&
event
->
data
,
size
);
set_req_data_size
(
req
,
size
);
}
else
/* timeout or error */
{
set_req_data_size
(
req
,
0
);
req
->
pid
=
0
;
req
->
tid
=
0
;
}
}
/* build a reply for the send_event request */
/* build a reply for the send_event request */
static
void
build_exception_event_reply
(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
)
static
void
build_exception_event_reply
(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
)
{
{
...
@@ -357,29 +326,6 @@ static void debug_ctx_destroy( struct object *obj )
...
@@ -357,29 +326,6 @@ static void debug_ctx_destroy( struct object *obj )
while
((
event
=
debug_ctx
->
event_head
)
!=
NULL
)
unlink_event
(
debug_ctx
,
event
);
while
((
event
=
debug_ctx
->
event_head
)
!=
NULL
)
unlink_event
(
debug_ctx
,
event
);
}
}
/* wait for a debug event (or send a reply at once if one is pending) */
static
int
wait_for_debug_event
(
int
timeout
)
{
struct
debug_ctx
*
debug_ctx
=
current
->
debug_ctx
;
struct
object
*
obj
=
&
debug_ctx
->
obj
;
int
flags
=
0
;
struct
timeval
tv
;
if
(
!
debug_ctx
)
/* current thread is not a debugger */
{
set_error
(
STATUS_INVALID_HANDLE
);
return
0
;
}
if
(
timeout
!=
-
1
)
{
flags
=
SELECT_TIMEOUT
;
gettimeofday
(
&
tv
,
0
);
add_timeout
(
&
tv
,
timeout
);
}
else
tv
.
tv_sec
=
tv
.
tv_usec
=
0
;
return
sleep_on
(
1
,
&
obj
,
flags
,
tv
.
tv_sec
,
tv
.
tv_usec
,
build_wait_debug_reply
);
}
/* continue a debug event */
/* continue a debug event */
static
int
continue_debug_event
(
struct
process
*
process
,
struct
thread
*
thread
,
int
status
)
static
int
continue_debug_event
(
struct
process
*
process
,
struct
thread
*
thread
,
int
status
)
{
{
...
@@ -539,11 +485,33 @@ void debug_exit_thread( struct thread *thread )
...
@@ -539,11 +485,33 @@ void debug_exit_thread( struct thread *thread )
/* Wait for a debug event */
/* Wait for a debug event */
DECL_HANDLER
(
wait_debug_event
)
DECL_HANDLER
(
wait_debug_event
)
{
{
if
(
!
wait_for_debug_event
(
req
->
timeout
))
struct
debug_ctx
*
debug_ctx
=
current
->
debug_ctx
;
struct
debug_event
*
event
;
if
(
!
debug_ctx
)
/* current thread is not a debugger */
{
set_error
(
STATUS_INVALID_HANDLE
);
return
;
}
req
->
wait
=
0
;
if
((
event
=
find_event_to_send
(
debug_ctx
)))
{
{
req
->
pid
=
NULL
;
size_t
size
=
get_req_data_size
(
req
);
req
->
tid
=
NULL
;
event
->
state
=
EVENT_SENT
;
event
->
sender
->
debug_event
=
event
;
req
->
pid
=
event
->
sender
->
process
;
req
->
tid
=
event
->
sender
;
if
(
size
>
sizeof
(
debug_event_t
))
size
=
sizeof
(
debug_event_t
);
memcpy
(
get_req_data
(
req
),
&
event
->
data
,
size
);
set_req_data_size
(
req
,
size
);
}
else
/* no event ready */
{
req
->
pid
=
0
;
req
->
tid
=
0
;
set_req_data_size
(
req
,
0
);
set_req_data_size
(
req
,
0
);
if
(
req
->
get_handle
)
req
->
wait
=
alloc_handle
(
current
->
process
,
debug_ctx
,
SYNCHRONIZE
,
FALSE
);
}
}
}
}
...
...
server/process.c
View file @
e9936d96
...
@@ -68,6 +68,7 @@ struct startup_info
...
@@ -68,6 +68,7 @@ struct startup_info
int
cmd_show
;
/* main window show mode */
int
cmd_show
;
/* main window show mode */
struct
file
*
exe_file
;
/* file handle for main exe */
struct
file
*
exe_file
;
/* file handle for main exe */
char
*
filename
;
/* file name for main exe */
char
*
filename
;
/* file name for main exe */
struct
thread
*
owner
;
/* owner thread (the one that created the new process) */
struct
process
*
process
;
/* created process */
struct
process
*
process
;
/* created process */
struct
thread
*
thread
;
/* created thread */
struct
thread
*
thread
;
/* created thread */
};
};
...
@@ -319,6 +320,11 @@ static void startup_info_destroy( struct object *obj )
...
@@ -319,6 +320,11 @@ static void startup_info_destroy( struct object *obj )
if
(
info
->
exe_file
)
release_object
(
info
->
exe_file
);
if
(
info
->
exe_file
)
release_object
(
info
->
exe_file
);
if
(
info
->
process
)
release_object
(
info
->
process
);
if
(
info
->
process
)
release_object
(
info
->
process
);
if
(
info
->
thread
)
release_object
(
info
->
thread
);
if
(
info
->
thread
)
release_object
(
info
->
thread
);
if
(
info
->
owner
)
{
info
->
owner
->
info
=
NULL
;
release_object
(
info
->
owner
);
}
}
}
static
void
startup_info_dump
(
struct
object
*
obj
,
int
verbose
)
static
void
startup_info_dump
(
struct
object
*
obj
,
int
verbose
)
...
@@ -337,33 +343,6 @@ static int startup_info_signaled( struct object *obj, struct thread *thread )
...
@@ -337,33 +343,6 @@ static int startup_info_signaled( struct object *obj, struct thread *thread )
}
}
/* build a reply for the wait_process request */
static
void
build_wait_process_reply
(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
)
{
struct
wait_process_request
*
req
=
get_req_ptr
(
thread
);
if
(
obj
)
{
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
assert
(
obj
->
ops
==
&
startup_info_ops
);
req
->
pid
=
get_process_id
(
info
->
process
);
req
->
tid
=
get_thread_id
(
info
->
thread
);
req
->
phandle
=
alloc_handle
(
thread
->
process
,
info
->
process
,
PROCESS_ALL_ACCESS
,
req
->
pinherit
);
req
->
thandle
=
alloc_handle
(
thread
->
process
,
info
->
thread
,
THREAD_ALL_ACCESS
,
req
->
tinherit
);
if
(
info
->
process
->
init_event
)
req
->
event
=
alloc_handle
(
thread
->
process
,
info
->
process
->
init_event
,
EVENT_ALL_ACCESS
,
0
);
else
req
->
event
=
0
;
/* FIXME: set_error */
}
release_object
(
thread
->
info
);
thread
->
info
=
NULL
;
}
/* get a process from an id (and increment the refcount) */
/* get a process from an id (and increment the refcount) */
struct
process
*
get_process_from_id
(
void
*
id
)
struct
process
*
get_process_from_id
(
void
*
id
)
{
{
...
@@ -731,52 +710,52 @@ DECL_HANDLER(new_process)
...
@@ -731,52 +710,52 @@ DECL_HANDLER(new_process)
info
->
cmd_show
=
req
->
cmd_show
;
info
->
cmd_show
=
req
->
cmd_show
;
info
->
exe_file
=
NULL
;
info
->
exe_file
=
NULL
;
info
->
filename
=
NULL
;
info
->
filename
=
NULL
;
info
->
owner
=
(
struct
thread
*
)
grab_object
(
current
);
info
->
process
=
NULL
;
info
->
process
=
NULL
;
info
->
thread
=
NULL
;
info
->
thread
=
NULL
;
if
(
req
->
exe_file
&&
if
(
req
->
exe_file
&&
!
(
info
->
exe_file
=
get_file_obj
(
current
->
process
,
req
->
exe_file
,
GENERIC_READ
)))
!
(
info
->
exe_file
=
get_file_obj
(
current
->
process
,
req
->
exe_file
,
GENERIC_READ
)))
{
goto
done
;
release_object
(
info
);
return
;
if
(
!
(
info
->
filename
=
mem_alloc
(
len
+
1
)))
goto
done
;
}
if
(
!
(
info
->
filename
=
mem_alloc
(
len
+
1
)))
{
release_object
(
info
);
return
;
}
memcpy
(
info
->
filename
,
get_req_data
(
req
),
len
);
memcpy
(
info
->
filename
,
get_req_data
(
req
),
len
);
info
->
filename
[
len
]
=
0
;
info
->
filename
[
len
]
=
0
;
current
->
info
=
info
;
current
->
info
=
info
;
req
->
info
=
alloc_handle
(
current
->
process
,
info
,
SYNCHRONIZE
,
FALSE
);
done
:
release_object
(
info
);
}
}
/*
Wait for the new process to start
*/
/*
Retrieve information about a newly started process
*/
DECL_HANDLER
(
wait_process
)
DECL_HANDLER
(
get_new_process_info
)
{
{
if
(
!
current
->
info
)
struct
startup_info
*
info
;
{
fatal_protocol_error
(
current
,
"wait_process: no process is being created
\n
"
);
req
->
event
=
0
;
return
;
}
if
((
info
=
(
struct
startup_info
*
)
get_handle_obj
(
current
->
process
,
req
->
info
,
req
->
pid
=
0
;
0
,
&
startup_info_ops
)))
req
->
tid
=
0
;
req
->
phandle
=
0
;
req
->
thandle
=
0
;
req
->
event
=
0
;
if
(
req
->
cancel
)
{
{
release_object
(
current
->
info
);
req
->
pid
=
get_process_id
(
info
->
process
);
current
->
info
=
NULL
;
req
->
tid
=
get_thread_id
(
info
->
thread
);
req
->
phandle
=
alloc_handle
(
current
->
process
,
info
->
process
,
PROCESS_ALL_ACCESS
,
req
->
pinherit
);
req
->
thandle
=
alloc_handle
(
current
->
process
,
info
->
thread
,
THREAD_ALL_ACCESS
,
req
->
tinherit
);
if
(
info
->
process
->
init_event
)
req
->
event
=
alloc_handle
(
current
->
process
,
info
->
process
->
init_event
,
EVENT_ALL_ACCESS
,
0
);
release_object
(
info
);
}
}
else
else
{
{
struct
timeval
timeout
;
req
->
pid
=
0
;
struct
object
*
obj
=
&
current
->
info
->
obj
;
req
->
tid
=
0
;
gettimeofday
(
&
timeout
,
0
);
req
->
phandle
=
0
;
add_timeout
(
&
timeout
,
req
->
timeout
);
req
->
thandle
=
0
;
sleep_on
(
1
,
&
obj
,
SELECT_TIMEOUT
,
timeout
.
tv_sec
,
timeout
.
tv_usec
,
build_wait_process_reply
);
}
}
}
}
...
...
server/request.h
View file @
e9936d96
...
@@ -71,7 +71,7 @@ inline static void set_req_data_size( const void *req, size_t size )
...
@@ -71,7 +71,7 @@ inline static void set_req_data_size( const void *req, size_t size )
/* ### make_requests begin ### */
/* ### make_requests begin ### */
DECL_HANDLER
(
new_process
);
DECL_HANDLER
(
new_process
);
DECL_HANDLER
(
wait_process
);
DECL_HANDLER
(
get_new_process_info
);
DECL_HANDLER
(
new_thread
);
DECL_HANDLER
(
new_thread
);
DECL_HANDLER
(
boot_done
);
DECL_HANDLER
(
boot_done
);
DECL_HANDLER
(
init_process
);
DECL_HANDLER
(
init_process
);
...
@@ -185,7 +185,7 @@ typedef void (*req_handler)( void *req );
...
@@ -185,7 +185,7 @@ typedef void (*req_handler)( void *req );
static
const
req_handler
req_handlers
[
REQ_NB_REQUESTS
]
=
static
const
req_handler
req_handlers
[
REQ_NB_REQUESTS
]
=
{
{
(
req_handler
)
req_new_process
,
(
req_handler
)
req_new_process
,
(
req_handler
)
req_
wait_process
,
(
req_handler
)
req_
get_new_process_info
,
(
req_handler
)
req_new_thread
,
(
req_handler
)
req_new_thread
,
(
req_handler
)
req_boot_done
,
(
req_handler
)
req_boot_done
,
(
req_handler
)
req_init_process
,
(
req_handler
)
req_init_process
,
...
...
server/trace.c
View file @
e9936d96
...
@@ -275,15 +275,19 @@ static void dump_new_process_request( const struct new_process_request *req )
...
@@ -275,15 +275,19 @@ static void dump_new_process_request( const struct new_process_request *req )
cur_pos
+=
dump_varargs_string
(
req
);
cur_pos
+=
dump_varargs_string
(
req
);
}
}
static
void
dump_
wait_process_request
(
const
struct
wait
_process_request
*
req
)
static
void
dump_
new_process_reply
(
const
struct
new
_process_request
*
req
)
{
{
fprintf
(
stderr
,
" info=%d"
,
req
->
info
);
}
static
void
dump_get_new_process_info_request
(
const
struct
get_new_process_info_request
*
req
)
{
fprintf
(
stderr
,
" info=%d,"
,
req
->
info
);
fprintf
(
stderr
,
" pinherit=%d,"
,
req
->
pinherit
);
fprintf
(
stderr
,
" pinherit=%d,"
,
req
->
pinherit
);
fprintf
(
stderr
,
" tinherit=%d,"
,
req
->
tinherit
);
fprintf
(
stderr
,
" tinherit=%d"
,
req
->
tinherit
);
fprintf
(
stderr
,
" timeout=%d,"
,
req
->
timeout
);
fprintf
(
stderr
,
" cancel=%d"
,
req
->
cancel
);
}
}
static
void
dump_
wait_process_reply
(
const
struct
wait_process
_request
*
req
)
static
void
dump_
get_new_process_info_reply
(
const
struct
get_new_process_info
_request
*
req
)
{
{
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" phandle=%d,"
,
req
->
phandle
);
fprintf
(
stderr
,
" phandle=%d,"
,
req
->
phandle
);
...
@@ -1050,13 +1054,14 @@ static void dump_next_module_reply( const struct next_module_request *req )
...
@@ -1050,13 +1054,14 @@ static void dump_next_module_reply( const struct next_module_request *req )
static
void
dump_wait_debug_event_request
(
const
struct
wait_debug_event_request
*
req
)
static
void
dump_wait_debug_event_request
(
const
struct
wait_debug_event_request
*
req
)
{
{
fprintf
(
stderr
,
"
timeout=%d"
,
req
->
timeout
);
fprintf
(
stderr
,
"
get_handle=%d"
,
req
->
get_handle
);
}
}
static
void
dump_wait_debug_event_reply
(
const
struct
wait_debug_event_request
*
req
)
static
void
dump_wait_debug_event_reply
(
const
struct
wait_debug_event_request
*
req
)
{
{
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" tid=%p,"
,
req
->
tid
);
fprintf
(
stderr
,
" tid=%p,"
,
req
->
tid
);
fprintf
(
stderr
,
" wait=%d,"
,
req
->
wait
);
fprintf
(
stderr
,
" event="
);
fprintf
(
stderr
,
" event="
);
cur_pos
+=
dump_varargs_debug_event
(
req
);
cur_pos
+=
dump_varargs_debug_event
(
req
);
}
}
...
@@ -1474,7 +1479,7 @@ static void dump_async_result_request( const struct async_result_request *req )
...
@@ -1474,7 +1479,7 @@ static void dump_async_result_request( const struct async_result_request *req )
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_
wait_process
_request
,
(
dump_func
)
dump_
get_new_process_info
_request
,
(
dump_func
)
dump_new_thread_request
,
(
dump_func
)
dump_new_thread_request
,
(
dump_func
)
dump_boot_done_request
,
(
dump_func
)
dump_boot_done_request
,
(
dump_func
)
dump_init_process_request
,
(
dump_func
)
dump_init_process_request
,
...
@@ -1584,8 +1589,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
...
@@ -1584,8 +1589,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
};
};
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
0
,
(
dump_func
)
dump_new_process_reply
,
(
dump_func
)
dump_
wait_process
_reply
,
(
dump_func
)
dump_
get_new_process_info
_reply
,
(
dump_func
)
dump_new_thread_reply
,
(
dump_func
)
dump_new_thread_reply
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_init_process_reply
,
(
dump_func
)
dump_init_process_reply
,
...
@@ -1696,7 +1701,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
...
@@ -1696,7 +1701,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
"new_process"
,
"new_process"
,
"
wait_process
"
,
"
get_new_process_info
"
,
"new_thread"
,
"new_thread"
,
"boot_done"
,
"boot_done"
,
"init_process"
,
"init_process"
,
...
...
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