server: Fetch the data for the debug events from the process memory views.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
72baffdb6d
commit
123023eac7
|
@ -1921,10 +1921,8 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
|
||||
SERVER_START_REQ( load_dll )
|
||||
{
|
||||
req->base = wine_server_client_ptr( *module );
|
||||
req->dbg_offset = nt->FileHeader.PointerToSymbolTable;
|
||||
req->dbg_size = nt->FileHeader.NumberOfSymbols;
|
||||
req->name = wine_server_client_ptr( &wm->ldr.FullDllName.Buffer );
|
||||
req->base = wine_server_client_ptr( *module );
|
||||
req->name = wine_server_client_ptr( &wm->ldr.FullDllName.Buffer );
|
||||
wine_server_add_data( req, wm->ldr.FullDllName.Buffer, wm->ldr.FullDllName.Length );
|
||||
wine_server_call( req );
|
||||
}
|
||||
|
|
|
@ -748,6 +748,8 @@ typedef struct
|
|||
unsigned int header_size;
|
||||
unsigned int file_size;
|
||||
unsigned int checksum;
|
||||
unsigned int dbg_offset;
|
||||
unsigned int dbg_size;
|
||||
client_cpu_t cpu;
|
||||
int __pad;
|
||||
} pe_image_info_t;
|
||||
|
@ -1124,12 +1126,10 @@ struct resume_thread_reply
|
|||
struct load_dll_request
|
||||
{
|
||||
struct request_header __header;
|
||||
data_size_t dbg_offset;
|
||||
char __pad_12[4];
|
||||
mod_handle_t base;
|
||||
client_ptr_t name;
|
||||
data_size_t dbg_size;
|
||||
/* VARARG(filename,unicode_str); */
|
||||
char __pad_36[4];
|
||||
};
|
||||
struct load_dll_reply
|
||||
{
|
||||
|
@ -6208,7 +6208,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 661
|
||||
#define SERVER_PROTOCOL_VERSION 662
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -138,19 +138,14 @@ static void fill_create_thread_event( struct debug_event *event, const void *arg
|
|||
|
||||
static void fill_create_process_event( struct debug_event *event, const void *arg )
|
||||
{
|
||||
struct thread *thread = event->sender;
|
||||
struct process *process = thread->process;
|
||||
struct process_dll *exe_module = get_process_exe_module( process );
|
||||
const client_ptr_t *entry = arg;
|
||||
|
||||
event->data.create_process.base = exe_module->base;
|
||||
event->data.create_process.start = *entry;
|
||||
event->data.create_process.dbg_offset = exe_module->dbg_offset;
|
||||
event->data.create_process.dbg_size = exe_module->dbg_size;
|
||||
const struct memory_view *view = arg;
|
||||
const pe_image_info_t *image_info = get_view_image_info( view, &event->data.create_process.base );
|
||||
|
||||
event->data.create_process.start = image_info->entry_point;
|
||||
event->data.create_process.dbg_offset = image_info->dbg_offset;
|
||||
event->data.create_process.dbg_size = image_info->dbg_size;
|
||||
/* the doc says write access too, but this doesn't seem a good idea */
|
||||
event->file = get_mapping_file( process, exe_module->base, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE );
|
||||
event->file = get_view_file( view, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE );
|
||||
}
|
||||
|
||||
static void fill_exit_thread_event( struct debug_event *event, const void *arg )
|
||||
|
@ -169,13 +164,13 @@ static void fill_load_dll_event( struct debug_event *event, const void *arg )
|
|||
{
|
||||
struct process *process = event->sender->process;
|
||||
const struct process_dll *dll = arg;
|
||||
struct memory_view *view = find_mapped_view( process, dll->base );
|
||||
const pe_image_info_t *image_info = get_view_image_info( view, &event->data.load_dll.base );
|
||||
|
||||
event->data.load_dll.handle = 0;
|
||||
event->data.load_dll.base = dll->base;
|
||||
event->data.load_dll.dbg_offset = dll->dbg_offset;
|
||||
event->data.load_dll.dbg_size = dll->dbg_size;
|
||||
event->data.load_dll.dbg_offset = image_info->dbg_offset;
|
||||
event->data.load_dll.dbg_size = image_info->dbg_size;
|
||||
event->data.load_dll.name = dll->name;
|
||||
event->file = get_mapping_file( process, dll->base, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE );
|
||||
event->file = get_view_file( view, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE );
|
||||
}
|
||||
|
||||
static void fill_unload_dll_event( struct debug_event *event, const void *arg )
|
||||
|
@ -498,7 +493,7 @@ static int debugger_attach( struct process *process, struct thread *debugger, st
|
|||
}
|
||||
process->debug_obj = debug_obj;
|
||||
process->debug_children = 0;
|
||||
generate_startup_debug_events( process, 0 );
|
||||
generate_startup_debug_events( process );
|
||||
resume_process( process );
|
||||
return 1;
|
||||
|
||||
|
@ -537,12 +532,14 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj )
|
|||
}
|
||||
|
||||
/* generate all startup events of a given process */
|
||||
void generate_startup_debug_events( struct process *process, client_ptr_t entry )
|
||||
void generate_startup_debug_events( struct process *process )
|
||||
{
|
||||
struct list *ptr;
|
||||
struct memory_view *view = get_exe_view( process );
|
||||
struct thread *thread, *first_thread = get_process_first_thread( process );
|
||||
|
||||
generate_debug_event( first_thread, DbgCreateProcessStateChange, &entry );
|
||||
if (!view) return;
|
||||
generate_debug_event( first_thread, DbgCreateProcessStateChange, view );
|
||||
ptr = list_head( &process->dlls ); /* skip main module reported in create process event */
|
||||
|
||||
/* generate ntdll.dll load event */
|
||||
|
|
|
@ -166,9 +166,12 @@ extern int is_file_executable( const char *name );
|
|||
|
||||
/* file mapping functions */
|
||||
|
||||
extern struct file *get_mapping_file( struct process *process, client_ptr_t base,
|
||||
unsigned int access, unsigned int sharing );
|
||||
extern const pe_image_info_t *get_mapping_image_info( struct process *process, client_ptr_t base );
|
||||
struct memory_view;
|
||||
|
||||
extern struct memory_view *find_mapped_view( struct process *process, client_ptr_t base );
|
||||
extern struct memory_view *get_exe_view( struct process *process );
|
||||
extern struct file *get_view_file( const struct memory_view *view, unsigned int access, unsigned int sharing );
|
||||
extern const pe_image_info_t *get_view_image_info( const struct memory_view *view, client_ptr_t *base );
|
||||
extern void free_mapped_views( struct process *process );
|
||||
extern int get_page_size(void);
|
||||
extern struct mapping *create_fd_mapping( struct object *root, const struct unicode_str *name, struct fd *fd,
|
||||
|
|
|
@ -305,7 +305,7 @@ static int create_temp_file( file_pos_t size )
|
|||
}
|
||||
|
||||
/* find a memory view from its base address */
|
||||
static struct memory_view *find_mapped_view( struct process *process, client_ptr_t base )
|
||||
struct memory_view *find_mapped_view( struct process *process, client_ptr_t base )
|
||||
{
|
||||
struct memory_view *view;
|
||||
|
||||
|
@ -316,6 +316,12 @@ static struct memory_view *find_mapped_view( struct process *process, client_ptr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* get the main exe memory view */
|
||||
struct memory_view *get_exe_view( struct process *process )
|
||||
{
|
||||
return LIST_ENTRY( list_head( &process->views ), struct memory_view, entry );
|
||||
}
|
||||
|
||||
/* add a view to the process list */
|
||||
static void add_process_view( struct process *process, struct memory_view *view )
|
||||
{
|
||||
|
@ -724,6 +730,8 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
|
||||
mapping->image.image_charact = nt.FileHeader.Characteristics;
|
||||
mapping->image.machine = nt.FileHeader.Machine;
|
||||
mapping->image.dbg_offset = nt.FileHeader.PointerToSymbolTable;
|
||||
mapping->image.dbg_size = nt.FileHeader.NumberOfSymbols;
|
||||
mapping->image.zerobits = 0; /* FIXME */
|
||||
mapping->image.file_size = file_size;
|
||||
mapping->image.loader_flags = clr_va && clr_size;
|
||||
|
@ -945,22 +953,18 @@ static struct mapping *get_mapping_obj( struct process *process, obj_handle_t ha
|
|||
return (struct mapping *)get_handle_obj( process, handle, access, &mapping_ops );
|
||||
}
|
||||
|
||||
/* open a new file for the file descriptor backing the mapping */
|
||||
struct file *get_mapping_file( struct process *process, client_ptr_t base,
|
||||
unsigned int access, unsigned int sharing )
|
||||
/* open a new file for the file descriptor backing the view */
|
||||
struct file *get_view_file( const struct memory_view *view, unsigned int access, unsigned int sharing )
|
||||
{
|
||||
struct memory_view *view = find_mapped_view( process, base );
|
||||
|
||||
if (!view || !view->fd) return NULL;
|
||||
if (!view->fd) return NULL;
|
||||
return create_file_for_fd_obj( view->fd, access, sharing );
|
||||
}
|
||||
|
||||
/* get the image info for a SEC_IMAGE mapping */
|
||||
const pe_image_info_t *get_mapping_image_info( struct process *process, client_ptr_t base )
|
||||
/* get the image info for a SEC_IMAGE mapped view */
|
||||
const pe_image_info_t *get_view_image_info( const struct memory_view *view, client_ptr_t *base )
|
||||
{
|
||||
struct memory_view *view = find_mapped_view( process, base );
|
||||
|
||||
if (!view || !(view->flags & SEC_IMAGE)) return NULL;
|
||||
if (!(view->flags & SEC_IMAGE)) return NULL;
|
||||
*base = view->base;
|
||||
return &view->image;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ extern void sock_init(void);
|
|||
|
||||
extern void generate_debug_event( struct thread *thread, int code, const void *arg );
|
||||
extern void resume_delayed_debug_events( struct thread *thread );
|
||||
extern void generate_startup_debug_events( struct process *process, client_ptr_t entry );
|
||||
extern void generate_startup_debug_events( struct process *process );
|
||||
|
||||
/* registry functions */
|
||||
|
||||
|
|
|
@ -1375,7 +1375,7 @@ DECL_HANDLER(init_process_done)
|
|||
current->entry_point = req->entry;
|
||||
|
||||
init_process_tracing( process );
|
||||
generate_startup_debug_events( process, req->entry );
|
||||
generate_startup_debug_events( process );
|
||||
set_process_startup_state( process, STARTUP_DONE );
|
||||
|
||||
if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL );
|
||||
|
@ -1432,9 +1432,10 @@ DECL_HANDLER(get_process_info)
|
|||
reply->debug_children = process->debug_children;
|
||||
if (get_reply_max_size())
|
||||
{
|
||||
client_ptr_t base;
|
||||
const pe_image_info_t *info;
|
||||
struct process_dll *exe = get_process_exe_module( process );
|
||||
if (exe && (info = get_mapping_image_info( process, exe->base )))
|
||||
struct memory_view *view = get_exe_view( process );
|
||||
if (view && (info = get_view_image_info( view, &base )))
|
||||
set_reply_data( info, min( sizeof(*info), get_reply_max_size() ));
|
||||
}
|
||||
release_object( process );
|
||||
|
@ -1556,9 +1557,7 @@ DECL_HANDLER(load_dll)
|
|||
|
||||
if ((dll = process_load_dll( current->process, req->base, get_req_data(), get_req_data_size() )))
|
||||
{
|
||||
dll->dbg_offset = req->dbg_offset;
|
||||
dll->dbg_size = req->dbg_size;
|
||||
dll->name = req->name;
|
||||
dll->name = req->name;
|
||||
/* only generate event if initialization is done */
|
||||
if (is_process_init_done( current->process ))
|
||||
generate_debug_event( current, DbgLoadDllStateChange, dll );
|
||||
|
|
|
@ -38,8 +38,6 @@ struct process_dll
|
|||
struct list entry; /* entry in per-process dll list */
|
||||
mod_handle_t base; /* dll base address (in process addr space) */
|
||||
client_ptr_t name; /* ptr to ptr to name (in process addr space) */
|
||||
int dbg_offset; /* debug info offset */
|
||||
int dbg_size; /* debug info size */
|
||||
data_size_t namelen; /* length of dll file name */
|
||||
WCHAR *filename; /* dll file name */
|
||||
};
|
||||
|
|
|
@ -764,6 +764,8 @@ typedef struct
|
|||
unsigned int header_size;
|
||||
unsigned int file_size;
|
||||
unsigned int checksum;
|
||||
unsigned int dbg_offset;
|
||||
unsigned int dbg_size;
|
||||
client_cpu_t cpu;
|
||||
int __pad;
|
||||
} pe_image_info_t;
|
||||
|
@ -1028,10 +1030,8 @@ typedef struct
|
|||
|
||||
/* Notify the server that a dll has been loaded */
|
||||
@REQ(load_dll)
|
||||
data_size_t dbg_offset; /* debug info offset */
|
||||
mod_handle_t base; /* base address */
|
||||
client_ptr_t name; /* ptr to ptr to name (in process addr space) */
|
||||
data_size_t dbg_size; /* debug info size */
|
||||
VARARG(filename,unicode_str); /* file name of dll */
|
||||
@END
|
||||
|
||||
|
|
|
@ -846,11 +846,9 @@ C_ASSERT( FIELD_OFFSET(struct resume_thread_request, handle) == 12 );
|
|||
C_ASSERT( sizeof(struct resume_thread_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct resume_thread_reply, count) == 8 );
|
||||
C_ASSERT( sizeof(struct resume_thread_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct load_dll_request, dbg_offset) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct load_dll_request, base) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct load_dll_request, name) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct load_dll_request, dbg_size) == 32 );
|
||||
C_ASSERT( sizeof(struct load_dll_request) == 40 );
|
||||
C_ASSERT( sizeof(struct load_dll_request) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct unload_dll_request, base) == 16 );
|
||||
C_ASSERT( sizeof(struct unload_dll_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct queue_apc_request, handle) == 12 );
|
||||
|
|
|
@ -1562,10 +1562,8 @@ static void dump_resume_thread_reply( const struct resume_thread_reply *req )
|
|||
|
||||
static void dump_load_dll_request( const struct load_dll_request *req )
|
||||
{
|
||||
fprintf( stderr, " dbg_offset=%u", req->dbg_offset );
|
||||
dump_uint64( ", base=", &req->base );
|
||||
dump_uint64( " base=", &req->base );
|
||||
dump_uint64( ", name=", &req->name );
|
||||
fprintf( stderr, ", dbg_size=%u", req->dbg_size );
|
||||
dump_varargs_unicode_str( ", filename=", cur_size );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue