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
05f0b71b
Commit
05f0b71b
authored
Mar 09, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Store the list of loaded dlls in the server, and generate debug events
internally.
parent
5fb54566
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
292 additions
and
241 deletions
+292
-241
elfdll.h
include/elfdll.h
+1
-1
module.h
include/module.h
+1
-3
pe_image.h
include/pe_image.h
+2
-2
process.h
include/process.h
+0
-2
server.h
include/server.h
+16
-7
elf.c
loader/elf.c
+3
-4
elfdll.c
loader/elfdll.c
+7
-9
module.c
loader/module.c
+16
-37
pe_image.c
loader/pe_image.c
+18
-17
builtin32.c
relay32/builtin32.c
+13
-10
client.c
scheduler/client.c
+0
-12
debugger.c
scheduler/debugger.c
+0
-37
process.c
scheduler/process.c
+0
-8
debugger.c
server/debugger.c
+72
-41
object.h
server/object.h
+2
-1
process.c
server/process.c
+98
-13
process.h
server/process.h
+12
-2
ptrace.c
server/ptrace.c
+8
-3
request.c
server/request.c
+0
-15
request.h
server/request.h
+4
-3
thread.c
server/thread.c
+3
-4
trace.c
server/trace.c
+16
-10
No files found.
include/elfdll.h
View file @
05f0b71b
...
...
@@ -4,7 +4,7 @@
#include "module.h"
#include "windef.h"
WINE_MODREF
*
ELFDLL_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
,
DWORD
*
err
);
WINE_MODREF
*
ELFDLL_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
);
HINSTANCE16
ELFDLL_LoadModule16
(
LPCSTR
libname
);
void
ELFDLL_UnloadLibrary
(
WINE_MODREF
*
wm
);
...
...
include/module.h
View file @
05f0b71b
...
...
@@ -157,7 +157,6 @@ typedef struct _wine_modref
#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010
#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
#define WINE_MODREF_DEBUG_EVENT_SENT 0x00000040
#define WINE_MODREF_MARKER 0x80000000
...
...
@@ -182,7 +181,6 @@ extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved );
extern
void
MODULE_DllProcessDetach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
);
extern
void
MODULE_DllThreadAttach
(
LPVOID
lpReserved
);
extern
void
MODULE_DllThreadDetach
(
LPVOID
lpReserved
);
extern
void
MODULE_SendLoadDLLEvents
(
void
);
extern
WINE_MODREF
*
MODULE_LoadLibraryExA
(
LPCSTR
libname
,
HFILE
hfile
,
DWORD
flags
);
extern
BOOL
MODULE_FreeLibrary
(
WINE_MODREF
*
wm
);
extern
WINE_MODREF
*
MODULE_FindModule
(
LPCSTR
path
);
...
...
@@ -235,7 +233,7 @@ extern void NE_DllProcessAttach( HMODULE16 hModule );
HGLOBAL16
NE_LoadPEResource
(
NE_MODULE
*
pModule
,
WORD
type
,
LPVOID
bits
,
DWORD
size
);
/* relay32/builtin.c */
extern
WINE_MODREF
*
BUILTIN32_LoadLibraryExA
(
LPCSTR
name
,
DWORD
flags
,
DWORD
*
err
);
extern
WINE_MODREF
*
BUILTIN32_LoadLibraryExA
(
LPCSTR
name
,
DWORD
flags
);
extern
HMODULE16
BUILTIN32_LoadExeModule
(
void
);
extern
void
BUILTIN32_UnloadLibrary
(
WINE_MODREF
*
wm
);
...
...
include/pe_image.h
View file @
05f0b71b
...
...
@@ -25,7 +25,7 @@ extern BOOL PE_EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LON
extern
BOOL
PE_EnumResourceLanguagesW
(
HMODULE
,
LPCWSTR
,
LPCWSTR
,
ENUMRESLANGPROCW
,
LONG
);
extern
HRSRC
PE_FindResourceExW
(
struct
_wine_modref
*
,
LPCWSTR
,
LPCWSTR
,
WORD
);
extern
DWORD
PE_SizeofResource
(
HMODULE
,
HRSRC
);
extern
struct
_wine_modref
*
PE_LoadLibraryExA
(
LPCSTR
,
DWORD
,
DWORD
*
);
extern
struct
_wine_modref
*
PE_LoadLibraryExA
(
LPCSTR
,
DWORD
);
extern
void
PE_UnloadLibrary
(
struct
_wine_modref
*
);
extern
HGLOBAL
PE_LoadResource
(
struct
_wine_modref
*
wm
,
HRSRC
);
extern
HMODULE
PE_LoadImage
(
HANDLE
hFile
,
LPCSTR
filename
,
WORD
*
version
);
...
...
@@ -64,7 +64,7 @@ typedef struct {
ELF_STDCALL_STUB
*
stubs
;
}
ELF_MODREF
;
extern
struct
_wine_modref
*
ELF_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
,
DWORD
*
err
);
extern
struct
_wine_modref
*
ELF_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
);
extern
void
ELF_UnloadLibrary
(
struct
_wine_modref
*
);
extern
FARPROC
ELF_FindExportedFunction
(
struct
_wine_modref
*
wm
,
LPCSTR
funcName
);
...
...
include/process.h
View file @
05f0b71b
...
...
@@ -170,8 +170,6 @@ extern void PROCESS_WalkProcess( void );
/* scheduler/debugger.c */
extern
DWORD
DEBUG_SendExceptionEvent
(
EXCEPTION_RECORD
*
rec
,
BOOL
first_chance
,
CONTEXT
*
ctx
);
extern
DWORD
DEBUG_SendLoadDLLEvent
(
HFILE
file
,
HMODULE
module
,
LPSTR
*
name
);
extern
DWORD
DEBUG_SendUnloadDLLEvent
(
HMODULE
module
);
static
inline
PDB
*
WINE_UNUSED
PROCESS_Current
(
void
)
{
...
...
include/server.h
View file @
05f0b71b
...
...
@@ -271,13 +271,22 @@ struct resume_thread_request
};
/*
Debugger support: freeze / unfreeze
*/
struct
debugger
_request
/*
Notify the server that a dll has been loaded
*/
struct
load_dll
_request
{
IN
int
op
;
/* operation type */
IN
int
handle
;
/* file handle */
IN
void
*
base
;
/* base address */
IN
int
dbg_offset
;
/* debug info offset */
IN
int
dbg_size
;
/* debug info size */
IN
void
*
name
;
/* ptr to ptr to name (in process addr space) */
};
enum
debugger_op
{
DEBUGGER_FREEZE_ALL
,
DEBUGGER_UNFREEZE_ALL
};
/* Notify the server that a dll is being unloaded */
struct
unload_dll_request
{
IN
void
*
base
;
/* base address */
};
/* Queue an APC for a thread */
...
...
@@ -1101,7 +1110,8 @@ enum request
REQ_SET_THREAD_INFO
,
REQ_SUSPEND_THREAD
,
REQ_RESUME_THREAD
,
REQ_DEBUGGER
,
REQ_LOAD_DLL
,
REQ_UNLOAD_DLL
,
REQ_QUEUE_APC
,
REQ_GET_APCS
,
REQ_CLOSE_HANDLE
,
...
...
@@ -1186,7 +1196,7 @@ enum request
REQ_NB_REQUESTS
};
#define SERVER_PROTOCOL_VERSION
1
#define SERVER_PROTOCOL_VERSION
2
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
...
...
@@ -1250,7 +1260,6 @@ static inline void server_strcpyAtoW( WCHAR *dst, const char *src )
extern
int
CLIENT_InitServer
(
void
);
extern
int
CLIENT_BootDone
(
int
debug_level
);
extern
int
CLIENT_IsBootThread
(
void
);
extern
int
CLIENT_DebuggerRequest
(
int
op
);
extern
int
CLIENT_InitThread
(
void
);
#endif
/* __WINE_SERVER__ */
...
...
loader/elf.c
View file @
05f0b71b
...
...
@@ -102,7 +102,7 @@ static WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
return
wm
;
}
WINE_MODREF
*
ELF_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
,
DWORD
*
err
)
WINE_MODREF
*
ELF_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
)
{
WINE_MODREF
*
wm
;
char
*
modname
,
*
s
,
*
t
,
*
x
;
...
...
@@ -146,7 +146,7 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err)
dlhandle
=
ELFDLL_dlopen
(
t
,
RTLD_NOW
);
if
(
!
dlhandle
)
{
HeapFree
(
GetProcessHeap
(),
0
,
t
);
*
err
=
ERROR_FILE_NOT_FOUND
;
SetLastError
(
ERROR_FILE_NOT_FOUND
)
;
return
NULL
;
}
...
...
@@ -154,7 +154,6 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err)
wm
->
binfmt
.
elf
.
dlhandle
=
dlhandle
;
SNOOP_RegisterDLL
(
wm
->
module
,
libname
,
STUBSIZE
/
sizeof
(
ELF_STDCALL_STUB
));
*
err
=
0
;
return
wm
;
}
...
...
@@ -271,7 +270,7 @@ void ELF_UnloadLibrary(WINE_MODREF *wm)
#else
WINE_MODREF
*
ELF_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
,
DWORD
*
err
)
WINE_MODREF
*
ELF_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
)
{
return
NULL
;
}
...
...
loader/elfdll.c
View file @
05f0b71b
...
...
@@ -284,7 +284,7 @@ static HMODULE16 ELFDLL_CreateNEModule(NE_MODULE *ne_image, DWORD size)
*
* Implementation of elf-dll loading for PE modules
*/
WINE_MODREF
*
ELFDLL_LoadLibraryExA
(
LPCSTR
path
,
DWORD
flags
,
DWORD
*
err
)
WINE_MODREF
*
ELFDLL_LoadLibraryExA
(
LPCSTR
path
,
DWORD
flags
)
{
LPVOID
dlhandle
;
struct
elfdll_image
*
image
;
...
...
@@ -302,7 +302,7 @@ WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
if
(
!
dlhandle
)
{
WARN
(
"Could not load %s (%s)
\n
"
,
soname
,
dlerror
());
*
err
=
ERROR_FILE_NOT_FOUND
;
SetLastError
(
ERROR_FILE_NOT_FOUND
)
;
return
NULL
;
}
...
...
@@ -314,7 +314,7 @@ WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
{
ERR
(
"Could not get elfdll image descriptor %s (%s)
\n
"
,
soname
,
dlerror
());
dlclose
(
dlhandle
);
*
err
=
ERROR_BAD_FORMAT
;
SetLastError
(
ERROR_BAD_FORMAT
)
;
return
NULL
;
}
...
...
@@ -324,7 +324,7 @@ WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
{
ERR
(
"Could not create win16 dummy module for %s
\n
"
,
path
);
dlclose
(
dlhandle
);
*
err
=
ERROR_OUTOFMEMORY
;
SetLastError
(
ERROR_OUTOFMEMORY
)
;
return
NULL
;
}
...
...
@@ -336,13 +336,11 @@ WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
ERR
(
"Could not create WINE_MODREF for %s
\n
"
,
path
);
GLOBAL_FreeBlock
((
HGLOBAL16
)
hmod16
);
dlclose
(
dlhandle
);
*
err
=
ERROR_OUTOFMEMORY
;
SetLastError
(
ERROR_OUTOFMEMORY
)
;
return
NULL
;
}
dump_exports
(
image
->
pe_module_start
);
*
err
=
0
;
return
wm
;
}
...
...
@@ -374,9 +372,9 @@ HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname)
* Just put stubs in here.
*/
WINE_MODREF
*
ELFDLL_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
,
DWORD
*
err
)
WINE_MODREF
*
ELFDLL_LoadLibraryExA
(
LPCSTR
libname
,
DWORD
flags
)
{
*
err
=
ERROR_FILE_NOT_FOUND
;
SetLastError
(
ERROR_FILE_NOT_FOUND
)
;
return
NULL
;
}
...
...
loader/module.c
View file @
05f0b71b
...
...
@@ -34,9 +34,10 @@
#include "callback.h"
#include "loadorder.h"
#include "elfdll.h"
#include "server.h"
DEFAULT_DEBUG_CHANNEL
(
module
)
DECLARE_DEBUG_CHANNEL
(
win32
)
DEFAULT_DEBUG_CHANNEL
(
module
)
;
DECLARE_DEBUG_CHANNEL
(
win32
)
;
/*************************************************************************
* MODULE_WalkModref
...
...
@@ -328,29 +329,6 @@ BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule )
return
retval
;
}
/*************************************************************************
* MODULE_SendLoadDLLEvents
*
* Sends DEBUG_DLL_LOAD events for all outstanding modules.
*
* NOTE: Assumes that the process critical section is held!
*
*/
void
MODULE_SendLoadDLLEvents
(
void
)
{
WINE_MODREF
*
wm
;
for
(
wm
=
PROCESS_Current
()
->
modref_list
;
wm
;
wm
=
wm
->
next
)
{
if
(
wm
->
type
!=
MODULE32_PE
)
continue
;
if
(
wm
==
PROCESS_Current
()
->
exe_modref
)
continue
;
if
(
wm
->
flags
&
WINE_MODREF_DEBUG_EVENT_SENT
)
continue
;
DEBUG_SendLoadDLLEvent
(
-
1
/*FIXME*/
,
wm
->
module
,
&
wm
->
modname
);
wm
->
flags
|=
WINE_MODREF_DEBUG_EVENT_SENT
;
}
}
/***********************************************************************
* MODULE_CreateDummyModule
...
...
@@ -1352,8 +1330,6 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
wm
=
MODULE_LoadLibraryExA
(
libname
,
hfile
,
flags
);
if
(
wm
)
{
MODULE_SendLoadDLLEvents
();
if
(
!
MODULE_DllProcessAttach
(
wm
,
NULL
)
)
{
WARN_
(
module
)(
"Attach failed for module '%s',
\n
"
,
libname
);
...
...
@@ -1381,7 +1357,7 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
*/
WINE_MODREF
*
MODULE_LoadLibraryExA
(
LPCSTR
libname
,
HFILE
hfile
,
DWORD
flags
)
{
DWORD
err
;
DWORD
err
=
GetLastError
()
;
WINE_MODREF
*
pwm
;
int
i
;
module_loadorder_t
*
plo
;
...
...
@@ -1402,26 +1378,27 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
for
(
i
=
0
;
i
<
MODULE_LOADORDER_NTYPES
;
i
++
)
{
SetLastError
(
ERROR_FILE_NOT_FOUND
);
switch
(
plo
->
loadorder
[
i
])
{
case
MODULE_LOADORDER_DLL
:
TRACE
(
"Trying native dll '%s'
\n
"
,
libname
);
pwm
=
PE_LoadLibraryExA
(
libname
,
flags
,
&
err
);
pwm
=
PE_LoadLibraryExA
(
libname
,
flags
);
break
;
case
MODULE_LOADORDER_ELFDLL
:
TRACE
(
"Trying elfdll '%s'
\n
"
,
libname
);
pwm
=
ELFDLL_LoadLibraryExA
(
libname
,
flags
,
&
err
);
pwm
=
ELFDLL_LoadLibraryExA
(
libname
,
flags
);
break
;
case
MODULE_LOADORDER_SO
:
TRACE
(
"Trying so-library '%s'
\n
"
,
libname
);
pwm
=
ELF_LoadLibraryExA
(
libname
,
flags
,
&
err
);
pwm
=
ELF_LoadLibraryExA
(
libname
,
flags
);
break
;
case
MODULE_LOADORDER_BI
:
TRACE
(
"Trying built-in '%s'
\n
"
,
libname
);
pwm
=
BUILTIN32_LoadLibraryExA
(
libname
,
flags
,
&
err
);
pwm
=
BUILTIN32_LoadLibraryExA
(
libname
,
flags
);
break
;
default:
...
...
@@ -1443,16 +1420,15 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
pwm
->
refCount
++
;
LeaveCriticalSection
(
&
PROCESS_Current
()
->
crit_section
);
SetLastError
(
err
);
/* restore last error */
return
pwm
;
}
if
(
err
!=
ERROR_FILE_NOT_FOUND
)
if
(
GetLastError
()
!=
ERROR_FILE_NOT_FOUND
)
break
;
}
WARN
(
"Failed to load module '%s'; error=0x%08lx,
\n
"
,
libname
,
err
);
SetLastError
(
err
);
WARN
(
"Failed to load module '%s'; error=0x%08lx,
\n
"
,
libname
,
GetLastError
());
LeaveCriticalSection
(
&
PROCESS_Current
()
->
crit_section
);
return
NULL
;
}
...
...
@@ -1610,8 +1586,11 @@ BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
/* Call process detach notifications */
if
(
PROCESS_Current
()
->
free_lib_count
<=
1
)
{
struct
unload_dll_request
*
req
=
get_req_buffer
();
MODULE_DllProcessDetach
(
FALSE
,
NULL
);
DEBUG_SendUnloadDLLEvent
(
wm
->
module
);
req
->
base
=
(
void
*
)
wm
->
module
;
server_call_noerr
(
REQ_UNLOAD_DLL
);
}
TRACE
(
"END
\n
"
);
...
...
loader/pe_image.c
View file @
05f0b71b
...
...
@@ -60,6 +60,7 @@
#include "global.h"
#include "task.h"
#include "snoop.h"
#include "server.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
win32
)
...
...
@@ -886,8 +887,9 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
* The PE Library Loader frontend.
* FIXME: handle the flags.
*/
WINE_MODREF
*
PE_LoadLibraryExA
(
LPCSTR
name
,
DWORD
flags
,
DWORD
*
err
)
WINE_MODREF
*
PE_LoadLibraryExA
(
LPCSTR
name
,
DWORD
flags
)
{
struct
load_dll_request
*
req
=
get_req_buffer
();
HMODULE
hModule32
;
HMODULE16
hModule16
;
NE_MODULE
*
pModule
;
...
...
@@ -898,33 +900,26 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags, DWORD *err)
/* Search for and open PE file */
if
(
SearchPathA
(
NULL
,
name
,
".DLL"
,
sizeof
(
filename
),
filename
,
NULL
)
==
0
)
{
*
err
=
ERROR_FILE_NOT_FOUND
;
return
NULL
;
}
sizeof
(
filename
),
filename
,
NULL
)
==
0
)
return
NULL
;
hFile
=
CreateFileA
(
filename
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
0
,
-
1
);
if
(
hFile
==
INVALID_HANDLE_VALUE
)
{
*
err
=
ERROR_FILE_NOT_FOUND
;
return
NULL
;
}
if
(
hFile
==
INVALID_HANDLE_VALUE
)
return
NULL
;
/* Load PE module */
hModule32
=
PE_LoadImage
(
hFile
,
filename
,
&
version
);
CloseHandle
(
hFile
);
if
(
!
hModule32
)
{
*
err
=
ERROR_OUTOFMEMORY
;
/* Not entirely right, but good enough */
CloseHandle
(
hFile
);
SetLastError
(
ERROR_OUTOFMEMORY
);
/* Not entirely right, but good enough */
return
NULL
;
}
/* Create 16-bit dummy module */
if
((
hModule16
=
MODULE_CreateDummyModule
(
filename
,
version
))
<
32
)
{
*
err
=
(
DWORD
)
hModule16
;
/* This should give the correct error */
CloseHandle
(
hFile
);
SetLastError
(
(
DWORD
)
hModule16
);
/* This should give the correct error */
return
NULL
;
}
pModule
=
(
NE_MODULE
*
)
GlobalLock16
(
hModule16
);
...
...
@@ -936,14 +931,20 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags, DWORD *err)
{
ERR
(
"can't load %s
\n
"
,
filename
);
FreeLibrary16
(
hModule16
);
*
err
=
ERROR_OUTOFMEMORY
;
CloseHandle
(
hFile
);
SetLastError
(
ERROR_OUTOFMEMORY
);
return
NULL
;
}
if
(
wm
->
binfmt
.
pe
.
pe_export
)
SNOOP_RegisterDLL
(
wm
->
module
,
wm
->
modname
,
wm
->
binfmt
.
pe
.
pe_export
->
NumberOfFunctions
);
*
err
=
0
;
req
->
handle
=
hFile
;
req
->
base
=
(
void
*
)
hModule32
;
req
->
dbg_offset
=
0
;
req
->
dbg_size
=
0
;
req
->
name
=
&
wm
->
modname
;
server_call_noerr
(
REQ_LOAD_DLL
);
CloseHandle
(
hFile
);
return
wm
;
}
...
...
relay32/builtin32.c
View file @
05f0b71b
...
...
@@ -18,6 +18,7 @@
#include "main.h"
#include "snoop.h"
#include "winerror.h"
#include "server.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
module
);
...
...
@@ -331,8 +332,9 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
* Partly copied from the original PE_ version.
*
*/
WINE_MODREF
*
BUILTIN32_LoadLibraryExA
(
LPCSTR
path
,
DWORD
flags
,
DWORD
*
err
)
WINE_MODREF
*
BUILTIN32_LoadLibraryExA
(
LPCSTR
path
,
DWORD
flags
)
{
struct
load_dll_request
*
req
=
get_req_buffer
();
HMODULE16
hModule16
;
NE_MODULE
*
pModule
;
WINE_MODREF
*
wm
;
...
...
@@ -352,25 +354,21 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
if
(
i
==
nb_dlls
)
{
*
err
=
ERROR_FILE_NOT_FOUND
;
SetLastError
(
ERROR_FILE_NOT_FOUND
)
;
return
NULL
;
}
/* Load built-in module */
if
(
!
dll_modules
[
i
])
{
if
(
!
(
dll_modules
[
i
]
=
BUILTIN32_DoLoadImage
(
builtin_dlls
[
i
]
)))
{
*
err
=
ERROR_FILE_NOT_FOUND
;
return
NULL
;
}
if
(
!
(
dll_modules
[
i
]
=
BUILTIN32_DoLoadImage
(
builtin_dlls
[
i
]
)))
return
NULL
;
}
else
BUILTIN32_WarnSecondInstance
(
builtin_dlls
[
i
]
->
name
);
/* Create 16-bit dummy module */
if
((
hModule16
=
MODULE_CreateDummyModule
(
dllname
,
0
))
<
32
)
{
*
err
=
(
DWORD
)
hModule16
;
SetLastError
(
(
DWORD
)
hModule16
)
;
return
NULL
;
/* FIXME: Should unload the builtin module */
}
...
...
@@ -383,14 +381,19 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
{
ERR
(
"can't load %s
\n
"
,
path
);
FreeLibrary16
(
hModule16
);
/* FIXME: Should unload the builtin module */
*
err
=
ERROR_OUTOFMEMORY
;
SetLastError
(
ERROR_OUTOFMEMORY
)
;
return
NULL
;
}
if
(
wm
->
binfmt
.
pe
.
pe_export
)
SNOOP_RegisterDLL
(
wm
->
module
,
wm
->
modname
,
wm
->
binfmt
.
pe
.
pe_export
->
NumberOfFunctions
);
*
err
=
0
;
req
->
handle
=
-
1
;
req
->
base
=
(
void
*
)
pModule
->
module32
;
req
->
dbg_offset
=
0
;
req
->
dbg_size
=
0
;
req
->
name
=
&
wm
->
modname
;
server_call_noerr
(
REQ_LOAD_DLL
);
return
wm
;
}
...
...
scheduler/client.c
View file @
05f0b71b
...
...
@@ -505,15 +505,3 @@ int CLIENT_IsBootThread(void)
{
return
(
GetCurrentThreadId
()
==
(
DWORD
)
boot_thread_id
);
}
/***********************************************************************
* CLIENT_DebuggerRequest
*
* Send a debugger support request. Return 0 if OK.
*/
int
CLIENT_DebuggerRequest
(
int
op
)
{
struct
debugger_request
*
req
=
get_req_buffer
();
req
->
op
=
op
;
return
server_call
(
REQ_DEBUGGER
);
}
scheduler/debugger.c
View file @
05f0b71b
...
...
@@ -40,43 +40,6 @@ DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEX
}
/**********************************************************************
* DEBUG_SendLoadDLLEvent
*
* Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
*/
DWORD
DEBUG_SendLoadDLLEvent
(
HFILE
file
,
HMODULE
module
,
LPSTR
*
name
)
{
struct
send_debug_event_request
*
req
=
get_req_buffer
();
req
->
event
.
code
=
LOAD_DLL_DEBUG_EVENT
;
req
->
event
.
info
.
load_dll
.
handle
=
file
;
req
->
event
.
info
.
load_dll
.
base
=
(
void
*
)
module
;
req
->
event
.
info
.
load_dll
.
dbg_offset
=
0
;
/* FIXME */
req
->
event
.
info
.
load_dll
.
dbg_size
=
0
;
/* FIXME */
req
->
event
.
info
.
load_dll
.
name
=
name
;
req
->
event
.
info
.
load_dll
.
unicode
=
0
;
server_call_noerr
(
REQ_SEND_DEBUG_EVENT
);
return
req
->
status
;
}
/**********************************************************************
* DEBUG_SendUnloadDLLEvent
*
* Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
*/
DWORD
DEBUG_SendUnloadDLLEvent
(
HMODULE
module
)
{
struct
send_debug_event_request
*
req
=
get_req_buffer
();
req
->
event
.
code
=
UNLOAD_DLL_DEBUG_EVENT
;
req
->
event
.
info
.
unload_dll
.
base
=
(
void
*
)
module
;
server_call_noerr
(
REQ_SEND_DEBUG_EVENT
);
return
req
->
status
;
}
/******************************************************************************
* WaitForDebugEvent (KERNEL32.720)
*
...
...
scheduler/process.c
View file @
05f0b71b
...
...
@@ -458,14 +458,6 @@ void PROCESS_Start(void)
server_call
(
REQ_INIT_PROCESS_DONE
);
debugged
=
req
->
debugged
;
/* Send all required start-up debugger events */
if
(
type
==
PROC_WIN32
&&
debugged
)
{
EnterCriticalSection
(
&
pdb
->
crit_section
);
MODULE_SendLoadDLLEvents
();
LeaveCriticalSection
(
&
pdb
->
crit_section
);
}
if
(
(
pdb
->
flags
&
PDB32_CONSOLE_PROC
)
||
(
pdb
->
flags
&
PDB32_DOS_PROC
)
)
AllocConsole
();
...
...
server/debugger.c
View file @
05f0b71b
...
...
@@ -84,72 +84,85 @@ static const struct object_ops debug_ctx_ops =
/* initialise the fields that do not need to be filled by the client */
static
int
fill_debug_event
(
struct
thread
*
debugger
,
struct
thread
*
thread
,
struct
debug_event
*
event
)
static
int
fill_debug_event
(
struct
debug_event
*
event
,
void
*
arg
)
{
struct
process
*
debugger
=
event
->
debugger
->
process
;
struct
process
*
process
;
struct
thread
*
thread
;
struct
process_dll
*
dll
;
int
handle
;
/* some events need special handling */
switch
(
event
->
data
.
code
)
{
case
CREATE_THREAD_DEBUG_EVENT
:
if
((
event
->
data
.
info
.
create_thread
.
handle
=
alloc_handle
(
debugger
->
process
,
thread
,
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
THREAD_ALL_ACCESS
,
FALSE
))
==
-
1
)
thread
=
arg
;
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
if
((
handle
=
alloc_handle
(
debugger
,
thread
,
THREAD_ALL_ACCESS
,
FALSE
))
==
-
1
)
return
0
;
event
->
data
.
info
.
create_thread
.
teb
=
thread
->
teb
;
event
->
data
.
info
.
create_thread
.
start
=
thread
->
entry
;
event
->
data
.
info
.
create_thread
.
handle
=
handle
;
event
->
data
.
info
.
create_thread
.
teb
=
thread
->
teb
;
event
->
data
.
info
.
create_thread
.
start
=
thread
->
entry
;
break
;
case
CREATE_PROCESS_DEBUG_EVENT
:
if
((
handle
=
alloc_handle
(
debugger
->
process
,
thread
->
process
,
/* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
PROCESS_ALL_ACCESS
,
FALSE
))
==
-
1
)
process
=
arg
;
thread
=
process
->
thread_list
;
/* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
if
((
handle
=
alloc_handle
(
debugger
,
process
,
PROCESS_ALL_ACCESS
,
FALSE
))
==
-
1
)
return
0
;
event
->
data
.
info
.
create_process
.
process
=
handle
;
if
((
handle
=
alloc_handle
(
debugger
->
process
,
thread
,
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
THREAD_ALL_ACCESS
,
FALSE
))
==
-
1
)
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
if
((
handle
=
alloc_handle
(
debugger
,
thread
,
THREAD_ALL_ACCESS
,
FALSE
))
==
-
1
)
{
close_handle
(
debugger
->
process
,
event
->
data
.
info
.
create_process
.
process
);
close_handle
(
debugger
,
event
->
data
.
info
.
create_process
.
process
);
return
0
;
}
event
->
data
.
info
.
create_process
.
thread
=
handle
;
handle
=
-
1
;
if
(
thread
->
process
->
exe_file
&&
((
handle
=
alloc_handle
(
debugger
->
process
,
thread
->
process
->
exe_file
,
/* the doc says write access too, but this doesn't seem a good idea */
GENERIC_READ
,
FALSE
))
==
-
1
))
if
(
process
->
exe
.
file
&&
/* the doc says write access too, but this doesn't seem a good idea */
((
handle
=
alloc_handle
(
debugger
,
process
->
exe
.
file
,
GENERIC_READ
,
FALSE
))
==
-
1
))
{
close_handle
(
debugger
->
process
,
event
->
data
.
info
.
create_process
.
process
);
close_handle
(
debugger
->
process
,
event
->
data
.
info
.
create_process
.
thread
);
close_handle
(
debugger
,
event
->
data
.
info
.
create_process
.
process
);
close_handle
(
debugger
,
event
->
data
.
info
.
create_process
.
thread
);
return
0
;
}
event
->
data
.
info
.
create_process
.
file
=
handle
;
event
->
data
.
info
.
create_process
.
teb
=
thread
->
teb
;
event
->
data
.
info
.
create_process
.
base
=
thread
->
process
->
modul
e
;
event
->
data
.
info
.
create_process
.
base
=
process
->
exe
.
bas
e
;
event
->
data
.
info
.
create_process
.
start
=
thread
->
entry
;
event
->
data
.
info
.
create_process
.
dbg_offset
=
0
;
event
->
data
.
info
.
create_process
.
dbg_size
=
0
;
event
->
data
.
info
.
create_process
.
dbg_offset
=
process
->
exe
.
dbg_offset
;
event
->
data
.
info
.
create_process
.
dbg_size
=
process
->
exe
.
dbg_size
;
event
->
data
.
info
.
create_process
.
name
=
0
;
event
->
data
.
info
.
create_process
.
unicode
=
0
;
break
;
case
LOAD_DLL_DEBUG_EVENT
:
if
((
handle
=
event
->
data
.
info
.
load_dll
.
handle
)
!=
-
1
)
{
if
((
handle
=
duplicate_handle
(
thread
->
process
,
handle
,
debugger
->
process
,
GENERIC_READ
,
FALSE
,
0
))
==
-
1
)
return
0
;
event
->
data
.
info
.
load_dll
.
handle
=
handle
;
}
dll
=
arg
;
handle
=
-
1
;
if
(
dll
->
file
&&
(
handle
=
alloc_handle
(
debugger
,
dll
->
file
,
GENERIC_READ
,
FALSE
))
==
-
1
)
return
0
;
event
->
data
.
info
.
load_dll
.
handle
=
handle
;
event
->
data
.
info
.
load_dll
.
base
=
dll
->
base
;
event
->
data
.
info
.
load_dll
.
dbg_offset
=
dll
->
dbg_offset
;
event
->
data
.
info
.
load_dll
.
dbg_size
=
dll
->
dbg_size
;
event
->
data
.
info
.
load_dll
.
name
=
dll
->
name
;
event
->
data
.
info
.
load_dll
.
unicode
=
0
;
break
;
case
EXIT_PROCESS_DEBUG_EVENT
:
process
=
arg
;
event
->
data
.
info
.
exit
.
exit_code
=
process
->
exit_code
;
break
;
case
EXIT_THREAD_DEBUG_EVENT
:
thread
=
arg
;
event
->
data
.
info
.
exit
.
exit_code
=
thread
->
exit_code
;
break
;
case
EXCEPTION_DEBUG_EVENT
:
case
UNLOAD_DLL_DEBUG_EVENT
:
event
->
data
.
info
.
unload_dll
.
base
=
arg
;
break
;
case
EXCEPTION_DEBUG_EVENT
:
case
OUTPUT_DEBUG_STRING_EVENT
:
case
RIP_EVENT
:
break
;
...
...
@@ -333,7 +346,6 @@ static int continue_debug_event( struct process *process, struct thread *thread,
{
if
(
event
==
debug_ctx
->
to_send
)
goto
error
;
if
(
event
->
sender
==
thread
)
break
;
event
=
event
->
next
;
}
if
(
!
event
)
goto
error
;
...
...
@@ -351,7 +363,7 @@ static int continue_debug_event( struct process *process, struct thread *thread,
}
/* queue a debug event for a debugger */
static
struct
debug_event
*
queue_debug_event
(
struct
thread
*
thread
,
int
code
,
static
struct
debug_event
*
queue_debug_event
(
struct
thread
*
thread
,
int
code
,
void
*
arg
,
debug_event_t
*
data
)
{
struct
thread
*
debugger
=
thread
->
process
->
debugger
;
...
...
@@ -372,7 +384,7 @@ static struct debug_event *queue_debug_event( struct thread *thread, int code,
if
(
data
)
memcpy
(
&
event
->
data
,
data
,
sizeof
(
event
->
data
)
);
event
->
data
.
code
=
code
;
if
(
!
fill_debug_event
(
debugger
,
thread
,
event
))
if
(
!
fill_debug_event
(
event
,
arg
))
{
event
->
data
.
code
=
-
1
;
/* make sure we don't attempt to close handles */
release_object
(
event
);
...
...
@@ -385,15 +397,35 @@ static struct debug_event *queue_debug_event( struct thread *thread, int code,
}
/* generate a debug event from inside the server and queue it */
void
generate_debug_event
(
struct
thread
*
thread
,
int
code
)
void
generate_debug_event
(
struct
thread
*
thread
,
int
code
,
void
*
arg
)
{
if
(
thread
->
process
->
debugger
)
{
struct
debug_event
*
event
=
queue_debug_event
(
thread
,
code
,
NULL
);
struct
debug_event
*
event
=
queue_debug_event
(
thread
,
code
,
arg
,
NULL
);
if
(
event
)
release_object
(
event
);
}
}
/* generate all startup events of a given process */
void
generate_startup_debug_events
(
struct
process
*
process
)
{
struct
process_dll
*
dll
;
struct
thread
*
thread
=
process
->
thread_list
;
/* generate creation events */
generate_debug_event
(
thread
,
CREATE_PROCESS_DEBUG_EVENT
,
process
);
while
((
thread
=
thread
->
next
))
generate_debug_event
(
thread
,
CREATE_THREAD_DEBUG_EVENT
,
thread
);
/* generate dll events (in loading order, i.e. reverse list order) */
for
(
dll
=
&
process
->
exe
;
dll
->
next
;
dll
=
dll
->
next
);
while
(
dll
!=
&
process
->
exe
)
{
generate_debug_event
(
process
->
thread_list
,
LOAD_DLL_DEBUG_EVENT
,
dll
);
dll
=
dll
->
prev
;
}
}
/* return a pointer to the context in case the thread is inside an exception event */
CONTEXT
*
get_debug_context
(
struct
thread
*
thread
)
{
...
...
@@ -487,10 +519,8 @@ DECL_HANDLER(debug_process)
if
(
!
process
)
return
;
if
(
debugger_attach
(
process
,
current
))
{
struct
thread
*
thread
=
process
->
thread_list
;
generate_debug_event
(
thread
,
CREATE_PROCESS_DEBUG_EVENT
);
while
((
thread
=
thread
->
next
))
generate_debug_event
(
thread
,
CREATE_THREAD_DEBUG_EVENT
);
/* FIXME: load dll + breakpoint exception events */
generate_startup_debug_events
(
process
);
/* FIXME: breakpoint exception event */
}
release_object
(
process
);
}
...
...
@@ -507,7 +537,8 @@ DECL_HANDLER(send_debug_event)
return
;
}
req
->
status
=
0
;
if
(
current
->
process
->
debugger
&&
((
event
=
queue_debug_event
(
current
,
code
,
&
req
->
event
))))
if
(
current
->
process
->
debugger
&&
((
event
=
queue_debug_event
(
current
,
code
,
NULL
,
&
req
->
event
))))
{
/* wait for continue_debug_event */
struct
object
*
obj
=
&
event
->
obj
;
...
...
server/object.h
View file @
05f0b71b
...
...
@@ -154,7 +154,8 @@ extern int free_console( struct process *process );
/* debugger functions */
extern
int
debugger_attach
(
struct
process
*
process
,
struct
thread
*
debugger
);
extern
void
generate_debug_event
(
struct
thread
*
thread
,
int
code
);
extern
void
generate_debug_event
(
struct
thread
*
thread
,
int
code
,
void
*
arg
);
extern
void
generate_startup_debug_events
(
struct
process
*
process
);
extern
void
debug_exit_thread
(
struct
thread
*
thread
);
extern
CONTEXT
*
get_debug_context
(
struct
thread
*
thread
);
...
...
server/process.c
View file @
05f0b71b
...
...
@@ -143,7 +143,6 @@ struct thread *create_process( int fd, struct process *parent,
process
->
prev
=
NULL
;
process
->
thread_list
=
NULL
;
process
->
debugger
=
NULL
;
process
->
exe_file
=
NULL
;
process
->
handles
=
NULL
;
process
->
exit_code
=
STILL_ACTIVE
;
process
->
running_threads
=
0
;
...
...
@@ -157,6 +156,11 @@ struct thread *create_process( int fd, struct process *parent,
process
->
info
=
NULL
;
process
->
ldt_copy
=
NULL
;
process
->
ldt_flags
=
NULL
;
process
->
exe
.
next
=
NULL
;
process
->
exe
.
prev
=
NULL
;
process
->
exe
.
file
=
NULL
;
process
->
exe
.
dbg_offset
=
0
;
process
->
exe
.
dbg_size
=
0
;
gettimeofday
(
&
process
->
start_time
,
NULL
);
if
((
process
->
next
=
first_process
)
!=
NULL
)
process
->
next
->
prev
=
process
;
first_process
=
process
;
...
...
@@ -176,7 +180,7 @@ struct thread *create_process( int fd, struct process *parent,
/* retrieve the main exe file */
if
(
process
->
info
->
exe_file
!=
-
1
)
{
if
(
!
(
process
->
exe
_
file
=
get_file_obj
(
parent
,
process
->
info
->
exe_file
,
if
(
!
(
process
->
exe
.
file
=
get_file_obj
(
parent
,
process
->
info
->
exe_file
,
GENERIC_READ
)))
goto
error
;
process
->
info
->
exe_file
=
-
1
;
}
...
...
@@ -225,7 +229,7 @@ static void process_destroy( struct object *obj )
else
first_process
=
process
->
next
;
if
(
process
->
info
)
free
(
process
->
info
);
if
(
process
->
init_event
)
release_object
(
process
->
init_event
);
if
(
process
->
exe
_file
)
release_object
(
process
->
exe_
file
);
if
(
process
->
exe
.
file
)
release_object
(
process
->
exe
.
file
);
}
/* dump a process on stdout for debugging purposes */
...
...
@@ -263,17 +267,68 @@ struct process *get_process_from_handle( int handle, unsigned int access )
access
,
&
process_ops
);
}
/* add a dll to a process list */
static
struct
process_dll
*
process_load_dll
(
struct
process
*
process
,
struct
file
*
file
,
void
*
base
)
{
struct
process_dll
*
dll
;
/* make sure we don't already have one with the same base address */
for
(
dll
=
process
->
exe
.
next
;
dll
;
dll
=
dll
->
next
)
if
(
dll
->
base
==
base
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
NULL
;
}
if
((
dll
=
mem_alloc
(
sizeof
(
*
dll
)
)))
{
dll
->
prev
=
&
process
->
exe
;
dll
->
file
=
NULL
;
dll
->
base
=
base
;
if
(
file
)
dll
->
file
=
(
struct
file
*
)
grab_object
(
file
);
if
((
dll
->
next
=
process
->
exe
.
next
))
dll
->
next
->
prev
=
dll
;
process
->
exe
.
next
=
dll
;
}
return
dll
;
}
/* remove a dll from a process list */
static
void
process_unload_dll
(
struct
process
*
process
,
void
*
base
)
{
struct
process_dll
*
dll
;
for
(
dll
=
process
->
exe
.
next
;
dll
;
dll
=
dll
->
next
)
{
if
(
dll
->
base
==
base
)
{
if
(
dll
->
file
)
release_object
(
dll
->
file
);
if
(
dll
->
next
)
dll
->
next
->
prev
=
dll
->
prev
;
if
(
dll
->
prev
)
dll
->
prev
->
next
=
dll
->
next
;
free
(
dll
);
generate_debug_event
(
current
,
UNLOAD_DLL_DEBUG_EVENT
,
base
);
return
;
}
}
set_error
(
STATUS_INVALID_PARAMETER
);
}
/* a process has been killed (i.e. its last thread died) */
static
void
process_killed
(
struct
process
*
process
,
int
exit_code
)
static
void
process_killed
(
struct
process
*
process
)
{
assert
(
!
process
->
thread_list
);
process
->
exit_code
=
exit_code
;
gettimeofday
(
&
process
->
end_time
,
NULL
);
release_object
(
process
->
handles
);
process
->
handles
=
NULL
;
free_console
(
process
);
if
(
process
->
exe_file
)
release_object
(
process
->
exe_file
);
process
->
exe_file
=
NULL
;
while
(
process
->
exe
.
next
)
{
struct
process_dll
*
dll
=
process
->
exe
.
next
;
process
->
exe
.
next
=
dll
->
next
;
if
(
dll
->
file
)
release_object
(
dll
->
file
);
free
(
dll
);
}
if
(
process
->
exe
.
file
)
release_object
(
process
->
exe
.
file
);
process
->
exe
.
file
=
NULL
;
wake_up
(
&
process
->
obj
,
0
);
if
(
!--
running_processes
)
{
...
...
@@ -308,8 +363,11 @@ void remove_process_thread( struct process *process, struct thread *thread )
if
(
!--
process
->
running_threads
)
{
/* we have removed the last running thread, exit the process */
process_killed
(
process
,
thread
->
exit_code
);
process
->
exit_code
=
thread
->
exit_code
;
generate_debug_event
(
thread
,
EXIT_PROCESS_DEBUG_EVENT
,
process
);
process_killed
(
process
);
}
else
generate_debug_event
(
thread
,
EXIT_THREAD_DEBUG_EVENT
,
thread
);
release_object
(
thread
);
}
...
...
@@ -580,8 +638,8 @@ DECL_HANDLER(init_process)
req
->
cmd_show
=
info
->
cmd_show
;
req
->
env_ptr
=
info
->
env_ptr
;
strcpy
(
req
->
cmdline
,
info
->
cmdline
);
if
(
current
->
process
->
exe
_
file
)
req
->
exe_file
=
alloc_handle
(
current
->
process
,
current
->
process
->
exe
_
file
,
if
(
current
->
process
->
exe
.
file
)
req
->
exe_file
=
alloc_handle
(
current
->
process
,
current
->
process
->
exe
.
file
,
GENERIC_READ
,
0
);
free
(
info
);
}
...
...
@@ -595,9 +653,9 @@ DECL_HANDLER(init_process_done)
fatal_protocol_error
(
current
,
"init_process_done: no event
\n
"
);
return
;
}
current
->
entry
=
req
->
entry
;
process
->
modul
e
=
req
->
module
;
generate_
debug_event
(
current
,
CREATE_PROCESS_DEBUG_EVENT
);
current
->
entry
=
req
->
entry
;
process
->
exe
.
bas
e
=
req
->
module
;
generate_
startup_debug_events
(
current
->
process
);
set_event
(
process
->
init_event
);
release_object
(
process
->
init_event
);
process
->
init_event
=
NULL
;
...
...
@@ -678,3 +736,30 @@ DECL_HANDLER(write_process_memory)
release_object
(
process
);
}
}
/* notify the server that a dll has been loaded */
DECL_HANDLER
(
load_dll
)
{
struct
process_dll
*
dll
;
struct
file
*
file
=
NULL
;
if
((
req
->
handle
!=
-
1
)
&&
!
(
file
=
get_file_obj
(
current
->
process
,
req
->
handle
,
GENERIC_READ
)))
return
;
if
((
dll
=
process_load_dll
(
current
->
process
,
file
,
req
->
base
)))
{
dll
->
dbg_offset
=
req
->
dbg_offset
;
dll
->
dbg_size
=
req
->
dbg_size
;
dll
->
name
=
req
->
name
;
/* only generate event if initialization is done */
if
(
!
current
->
process
->
init_event
)
generate_debug_event
(
current
,
LOAD_DLL_DEBUG_EVENT
,
dll
);
}
if
(
file
)
release_object
(
file
);
}
/* notify the server that a dll is being unloaded */
DECL_HANDLER
(
unload_dll
)
{
process_unload_dll
(
current
->
process
,
req
->
base
);
}
server/process.h
View file @
05f0b71b
...
...
@@ -15,6 +15,17 @@
/* process structures */
struct
process_dll
{
struct
process_dll
*
next
;
/* per-process dll list */
struct
process_dll
*
prev
;
struct
file
*
file
;
/* dll file */
void
*
base
;
/* dll base address (in process addr space) */
void
*
name
;
/* ptr to ptr to name (in process addr space) */
int
dbg_offset
;
/* debug info offset */
int
dbg_size
;
/* debug info size */
};
struct
process
{
struct
object
obj
;
/* object header */
...
...
@@ -22,7 +33,6 @@ struct process
struct
process
*
prev
;
struct
thread
*
thread_list
;
/* head of the thread list */
struct
thread
*
debugger
;
/* thread debugging this process */
struct
file
*
exe_file
;
/* main exe file */
struct
object
*
handles
;
/* handle entries */
int
exit_code
;
/* process exit code */
int
running_threads
;
/* number of threads running in this process */
...
...
@@ -35,9 +45,9 @@ struct process
struct
object
*
console_in
;
/* console input */
struct
object
*
console_out
;
/* console output */
struct
event
*
init_event
;
/* event for init done */
struct
process_dll
exe
;
/* main exe file */
void
*
ldt_copy
;
/* pointer to LDT copy in client addr space */
void
*
ldt_flags
;
/* pointer to LDT flags in client addr space */
void
*
module
;
/* main module base address */
struct
new_process_request
*
info
;
/* startup info (freed after startup) */
};
...
...
server/ptrace.c
View file @
05f0b71b
...
...
@@ -120,15 +120,20 @@ static int attach_thread( struct thread *thread )
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
);
/* make sure it is stopped */
if
(
!
(
thread
->
suspend
+
thread
->
process
->
suspend
))
stop_thread
(
thread
);
kill
(
thread
->
unix_pid
,
SIGTERM
);
if
(
debug_level
)
fprintf
(
stderr
,
"%08x: *detached*
\n
"
,
(
unsigned
int
)
thread
);
ptrace
(
PTRACE_DETACH
,
thread
->
unix_pid
,
1
,
SIGTERM
);
thread
->
attached
=
0
;
}
else
{
kill
(
thread
->
unix_pid
,
SIGTERM
);
if
(
thread
->
suspend
+
thread
->
process
->
suspend
)
continue_thread
(
thread
);
}
}
/* stop a thread (at the Unix level) */
...
...
server/request.c
View file @
05f0b71b
...
...
@@ -383,18 +383,3 @@ void lock_master_socket( int locked )
{
set_select_events
(
&
master_socket
->
obj
,
locked
?
0
:
POLLIN
);
}
/* debugger support operations */
DECL_HANDLER
(
debugger
)
{
switch
(
req
->
op
)
{
case
DEBUGGER_FREEZE_ALL
:
suspend_all_threads
();
break
;
case
DEBUGGER_UNFREEZE_ALL
:
resume_all_threads
();
break
;
}
}
server/request.h
View file @
05f0b71b
...
...
@@ -36,7 +36,6 @@ extern void close_master_socket(void);
extern
void
lock_master_socket
(
int
locked
);
extern
void
trace_request
(
enum
request
req
,
int
fd
);
extern
void
trace_kill
(
struct
thread
*
thread
);
extern
void
trace_reply
(
struct
thread
*
thread
);
/* get the request buffer */
...
...
@@ -85,7 +84,8 @@ DECL_HANDLER(get_thread_info);
DECL_HANDLER
(
set_thread_info
);
DECL_HANDLER
(
suspend_thread
);
DECL_HANDLER
(
resume_thread
);
DECL_HANDLER
(
debugger
);
DECL_HANDLER
(
load_dll
);
DECL_HANDLER
(
unload_dll
);
DECL_HANDLER
(
queue_apc
);
DECL_HANDLER
(
get_apcs
);
DECL_HANDLER
(
close_handle
);
...
...
@@ -189,7 +189,8 @@ static const struct handler {
{
(
void
(
*
)())
req_set_thread_info
,
sizeof
(
struct
set_thread_info_request
)
},
{
(
void
(
*
)())
req_suspend_thread
,
sizeof
(
struct
suspend_thread_request
)
},
{
(
void
(
*
)())
req_resume_thread
,
sizeof
(
struct
resume_thread_request
)
},
{
(
void
(
*
)())
req_debugger
,
sizeof
(
struct
debugger_request
)
},
{
(
void
(
*
)())
req_load_dll
,
sizeof
(
struct
load_dll_request
)
},
{
(
void
(
*
)())
req_unload_dll
,
sizeof
(
struct
unload_dll_request
)
},
{
(
void
(
*
)())
req_queue_apc
,
sizeof
(
struct
queue_apc_request
)
},
{
(
void
(
*
)())
req_get_apcs
,
sizeof
(
struct
get_apcs_request
)
},
{
(
void
(
*
)())
req_close_handle
,
sizeof
(
struct
close_handle_request
)
},
...
...
server/thread.c
View file @
05f0b71b
...
...
@@ -563,10 +563,9 @@ void kill_thread( struct thread *thread, int exit_code )
thread
->
state
=
TERMINATED
;
thread
->
exit_code
=
exit_code
;
if
(
current
==
thread
)
current
=
NULL
;
if
(
debug_level
)
trace_kill
(
thread
);
if
(
debug_level
)
fprintf
(
stderr
,
"%08x: *killed* exit_code=%d
\n
"
,
(
unsigned
int
)
thread
,
exit_code
);
if
(
thread
->
wait
)
end_wait
(
thread
);
generate_debug_event
(
thread
,
(
thread
->
process
->
running_threads
==
1
)
?
EXIT_PROCESS_DEBUG_EVENT
:
EXIT_THREAD_DEBUG_EVENT
);
debug_exit_thread
(
thread
);
abandon_mutexes
(
thread
);
remove_process_thread
(
thread
->
process
,
thread
);
...
...
@@ -633,7 +632,7 @@ DECL_HANDLER(init_thread)
current
->
entry
=
req
->
entry
;
if
(
current
->
suspend
+
current
->
process
->
suspend
>
0
)
stop_thread
(
current
);
if
(
current
->
process
->
running_threads
>
1
)
generate_debug_event
(
current
,
CREATE_THREAD_DEBUG_EVENT
);
generate_debug_event
(
current
,
CREATE_THREAD_DEBUG_EVENT
,
current
);
}
/* terminate a thread */
...
...
server/trace.c
View file @
05f0b71b
...
...
@@ -361,9 +361,18 @@ static void dump_resume_thread_reply( const struct resume_thread_request *req )
fprintf
(
stderr
,
" count=%d"
,
req
->
count
);
}
static
void
dump_
debugger_request
(
const
struct
debugger
_request
*
req
)
static
void
dump_
load_dll_request
(
const
struct
load_dll
_request
*
req
)
{
fprintf
(
stderr
,
" op=%d"
,
req
->
op
);
fprintf
(
stderr
,
" handle=%d,"
,
req
->
handle
);
fprintf
(
stderr
,
" base=%p,"
,
req
->
base
);
fprintf
(
stderr
,
" dbg_offset=%d,"
,
req
->
dbg_offset
);
fprintf
(
stderr
,
" dbg_size=%d,"
,
req
->
dbg_size
);
fprintf
(
stderr
,
" name=%p"
,
req
->
name
);
}
static
void
dump_unload_dll_request
(
const
struct
unload_dll_request
*
req
)
{
fprintf
(
stderr
,
" base=%p"
,
req
->
base
);
}
static
void
dump_queue_apc_request
(
const
struct
queue_apc_request
*
req
)
...
...
@@ -1247,7 +1256,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_set_thread_info_request
,
(
dump_func
)
dump_suspend_thread_request
,
(
dump_func
)
dump_resume_thread_request
,
(
dump_func
)
dump_debugger_request
,
(
dump_func
)
dump_load_dll_request
,
(
dump_func
)
dump_unload_dll_request
,
(
dump_func
)
dump_queue_apc_request
,
(
dump_func
)
dump_get_apcs_request
,
(
dump_func
)
dump_close_handle_request
,
...
...
@@ -1349,6 +1359,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_resume_thread_reply
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_get_apcs_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_get_handle_info_reply
,
...
...
@@ -1447,7 +1458,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_thread_info"
,
"suspend_thread"
,
"resume_thread"
,
"debugger"
,
"load_dll"
,
"unload_dll"
,
"queue_apc"
,
"get_apcs"
,
"close_handle"
,
...
...
@@ -1548,12 +1560,6 @@ void trace_request( enum request req, int fd )
else
fprintf
(
stderr
,
" )
\n
"
);
}
void
trace_kill
(
struct
thread
*
thread
)
{
fprintf
(
stderr
,
"%08x: *killed* exit_code=%d
\n
"
,
(
unsigned
int
)
thread
,
thread
->
exit_code
);
}
void
trace_reply
(
struct
thread
*
thread
)
{
fprintf
(
stderr
,
"%08x: %s() = %x"
,
...
...
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