server: Simplify the debug_event_t structure.
This commit is contained in:
parent
9087e5c55f
commit
bc03f0ee39
|
@ -74,51 +74,51 @@ BOOL WINAPI WaitForDebugEvent(
|
||||||
switch(data.code)
|
switch(data.code)
|
||||||
{
|
{
|
||||||
case EXCEPTION_DEBUG_EVENT:
|
case EXCEPTION_DEBUG_EVENT:
|
||||||
event->u.Exception.ExceptionRecord = data.info.exception.record;
|
event->u.Exception.ExceptionRecord = data.exception.record;
|
||||||
event->u.Exception.dwFirstChance = data.info.exception.first;
|
event->u.Exception.dwFirstChance = data.exception.first;
|
||||||
break;
|
break;
|
||||||
case CREATE_THREAD_DEBUG_EVENT:
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
event->u.CreateThread.hThread = wine_server_ptr_handle( data.info.create_thread.handle );
|
event->u.CreateThread.hThread = wine_server_ptr_handle( data.create_thread.handle );
|
||||||
event->u.CreateThread.lpThreadLocalBase = wine_server_get_ptr( data.info.create_thread.teb );
|
event->u.CreateThread.lpThreadLocalBase = wine_server_get_ptr( data.create_thread.teb );
|
||||||
event->u.CreateThread.lpStartAddress = wine_server_get_ptr( data.info.create_thread.start );
|
event->u.CreateThread.lpStartAddress = wine_server_get_ptr( data.create_thread.start );
|
||||||
break;
|
break;
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
event->u.CreateProcessInfo.hFile = wine_server_ptr_handle( data.info.create_process.file );
|
event->u.CreateProcessInfo.hFile = wine_server_ptr_handle( data.create_process.file );
|
||||||
event->u.CreateProcessInfo.hProcess = wine_server_ptr_handle( data.info.create_process.process );
|
event->u.CreateProcessInfo.hProcess = wine_server_ptr_handle( data.create_process.process );
|
||||||
event->u.CreateProcessInfo.hThread = wine_server_ptr_handle( data.info.create_process.thread );
|
event->u.CreateProcessInfo.hThread = wine_server_ptr_handle( data.create_process.thread );
|
||||||
event->u.CreateProcessInfo.lpBaseOfImage = wine_server_get_ptr( data.info.create_process.base );
|
event->u.CreateProcessInfo.lpBaseOfImage = wine_server_get_ptr( data.create_process.base );
|
||||||
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.info.create_process.dbg_offset;
|
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.create_process.dbg_offset;
|
||||||
event->u.CreateProcessInfo.nDebugInfoSize = data.info.create_process.dbg_size;
|
event->u.CreateProcessInfo.nDebugInfoSize = data.create_process.dbg_size;
|
||||||
event->u.CreateProcessInfo.lpThreadLocalBase = wine_server_get_ptr( data.info.create_process.teb );
|
event->u.CreateProcessInfo.lpThreadLocalBase = wine_server_get_ptr( data.create_process.teb );
|
||||||
event->u.CreateProcessInfo.lpStartAddress = wine_server_get_ptr( data.info.create_process.start );
|
event->u.CreateProcessInfo.lpStartAddress = wine_server_get_ptr( data.create_process.start );
|
||||||
event->u.CreateProcessInfo.lpImageName = wine_server_get_ptr( data.info.create_process.name );
|
event->u.CreateProcessInfo.lpImageName = wine_server_get_ptr( data.create_process.name );
|
||||||
event->u.CreateProcessInfo.fUnicode = data.info.create_process.unicode;
|
event->u.CreateProcessInfo.fUnicode = data.create_process.unicode;
|
||||||
break;
|
break;
|
||||||
case EXIT_THREAD_DEBUG_EVENT:
|
case EXIT_THREAD_DEBUG_EVENT:
|
||||||
event->u.ExitThread.dwExitCode = data.info.exit.exit_code;
|
event->u.ExitThread.dwExitCode = data.exit.exit_code;
|
||||||
break;
|
break;
|
||||||
case EXIT_PROCESS_DEBUG_EVENT:
|
case EXIT_PROCESS_DEBUG_EVENT:
|
||||||
event->u.ExitProcess.dwExitCode = data.info.exit.exit_code;
|
event->u.ExitProcess.dwExitCode = data.exit.exit_code;
|
||||||
break;
|
break;
|
||||||
case LOAD_DLL_DEBUG_EVENT:
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
event->u.LoadDll.hFile = wine_server_ptr_handle( data.info.load_dll.handle );
|
event->u.LoadDll.hFile = wine_server_ptr_handle( data.load_dll.handle );
|
||||||
event->u.LoadDll.lpBaseOfDll = wine_server_get_ptr( data.info.load_dll.base );
|
event->u.LoadDll.lpBaseOfDll = wine_server_get_ptr( data.load_dll.base );
|
||||||
event->u.LoadDll.dwDebugInfoFileOffset = data.info.load_dll.dbg_offset;
|
event->u.LoadDll.dwDebugInfoFileOffset = data.load_dll.dbg_offset;
|
||||||
event->u.LoadDll.nDebugInfoSize = data.info.load_dll.dbg_size;
|
event->u.LoadDll.nDebugInfoSize = data.load_dll.dbg_size;
|
||||||
event->u.LoadDll.lpImageName = wine_server_get_ptr( data.info.load_dll.name );
|
event->u.LoadDll.lpImageName = wine_server_get_ptr( data.load_dll.name );
|
||||||
event->u.LoadDll.fUnicode = data.info.load_dll.unicode;
|
event->u.LoadDll.fUnicode = data.load_dll.unicode;
|
||||||
break;
|
break;
|
||||||
case UNLOAD_DLL_DEBUG_EVENT:
|
case UNLOAD_DLL_DEBUG_EVENT:
|
||||||
event->u.UnloadDll.lpBaseOfDll = wine_server_get_ptr( data.info.unload_dll.base );
|
event->u.UnloadDll.lpBaseOfDll = wine_server_get_ptr( data.unload_dll.base );
|
||||||
break;
|
break;
|
||||||
case OUTPUT_DEBUG_STRING_EVENT:
|
case OUTPUT_DEBUG_STRING_EVENT:
|
||||||
event->u.DebugString.lpDebugStringData = wine_server_get_ptr( data.info.output_string.string );
|
event->u.DebugString.lpDebugStringData = wine_server_get_ptr( data.output_string.string );
|
||||||
event->u.DebugString.fUnicode = data.info.output_string.unicode;
|
event->u.DebugString.fUnicode = data.output_string.unicode;
|
||||||
event->u.DebugString.nDebugStringLength = data.info.output_string.length;
|
event->u.DebugString.nDebugStringLength = data.output_string.length;
|
||||||
break;
|
break;
|
||||||
case RIP_EVENT:
|
case RIP_EVENT:
|
||||||
event->u.RipInfo.dwError = data.info.rip_info.error;
|
event->u.RipInfo.dwError = data.rip_info.error;
|
||||||
event->u.RipInfo.dwType = data.info.rip_info.type;
|
event->u.RipInfo.dwType = data.rip_info.type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
|
|
@ -54,19 +54,25 @@ struct request_max_size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct debug_event_exception
|
typedef union
|
||||||
{
|
{
|
||||||
EXCEPTION_RECORD record;
|
int code;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int code;
|
||||||
int first;
|
int first;
|
||||||
};
|
EXCEPTION_RECORD record;
|
||||||
struct debug_event_create_thread
|
} exception;
|
||||||
{
|
struct
|
||||||
|
{
|
||||||
|
int code;
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
client_ptr_t teb;
|
client_ptr_t teb;
|
||||||
client_ptr_t start;
|
client_ptr_t start;
|
||||||
};
|
} create_thread;
|
||||||
struct debug_event_create_process
|
struct
|
||||||
{
|
{
|
||||||
|
int code;
|
||||||
obj_handle_t file;
|
obj_handle_t file;
|
||||||
obj_handle_t process;
|
obj_handle_t process;
|
||||||
obj_handle_t thread;
|
obj_handle_t thread;
|
||||||
|
@ -77,52 +83,41 @@ struct debug_event_create_process
|
||||||
client_ptr_t start;
|
client_ptr_t start;
|
||||||
client_ptr_t name;
|
client_ptr_t name;
|
||||||
int unicode;
|
int unicode;
|
||||||
};
|
} create_process;
|
||||||
struct debug_event_exit
|
struct
|
||||||
{
|
{
|
||||||
|
int code;
|
||||||
int exit_code;
|
int exit_code;
|
||||||
};
|
} exit;
|
||||||
struct debug_event_load_dll
|
struct
|
||||||
{
|
{
|
||||||
|
int code;
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
mod_handle_t base;
|
mod_handle_t base;
|
||||||
int dbg_offset;
|
int dbg_offset;
|
||||||
int dbg_size;
|
int dbg_size;
|
||||||
client_ptr_t name;
|
client_ptr_t name;
|
||||||
int unicode;
|
int unicode;
|
||||||
};
|
} load_dll;
|
||||||
struct debug_event_unload_dll
|
struct
|
||||||
{
|
{
|
||||||
|
int code;
|
||||||
|
int __pad;
|
||||||
mod_handle_t base;
|
mod_handle_t base;
|
||||||
};
|
} unload_dll;
|
||||||
struct debug_event_output_string
|
struct
|
||||||
{
|
{
|
||||||
client_ptr_t string;
|
int code;
|
||||||
int unicode;
|
int unicode;
|
||||||
|
client_ptr_t string;
|
||||||
data_size_t length;
|
data_size_t length;
|
||||||
};
|
} output_string;
|
||||||
struct debug_event_rip_info
|
struct
|
||||||
{
|
{
|
||||||
|
int code;
|
||||||
int error;
|
int error;
|
||||||
int type;
|
int type;
|
||||||
};
|
} rip_info;
|
||||||
union debug_event_data
|
|
||||||
{
|
|
||||||
struct debug_event_exception exception;
|
|
||||||
struct debug_event_create_thread create_thread;
|
|
||||||
struct debug_event_create_process create_process;
|
|
||||||
struct debug_event_exit exit;
|
|
||||||
struct debug_event_load_dll load_dll;
|
|
||||||
struct debug_event_unload_dll unload_dll;
|
|
||||||
struct debug_event_output_string output_string;
|
|
||||||
struct debug_event_rip_info rip_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
union debug_event_data info;
|
|
||||||
} debug_event_t;
|
} debug_event_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -5063,6 +5058,6 @@ union generic_reply
|
||||||
struct set_window_layered_info_reply set_window_layered_info_reply;
|
struct set_window_layered_info_reply set_window_layered_info_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 378
|
#define SERVER_PROTOCOL_VERSION 379
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -114,7 +114,8 @@ static const struct object_ops debug_ctx_ops =
|
||||||
|
|
||||||
static int fill_exception_event( struct debug_event *event, const void *arg )
|
static int fill_exception_event( struct debug_event *event, const void *arg )
|
||||||
{
|
{
|
||||||
memcpy( &event->data.info.exception, arg, sizeof(event->data.info.exception) );
|
const debug_event_t *data = arg;
|
||||||
|
event->data.exception = data->exception;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +128,9 @@ static int fill_create_thread_event( struct debug_event *event, const void *arg
|
||||||
|
|
||||||
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
|
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
|
||||||
if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 ))) return 0;
|
if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 ))) return 0;
|
||||||
event->data.info.create_thread.handle = handle;
|
event->data.create_thread.handle = handle;
|
||||||
event->data.info.create_thread.teb = thread->teb;
|
event->data.create_thread.teb = thread->teb;
|
||||||
if (entry) event->data.info.create_thread.start = *entry;
|
if (entry) event->data.create_thread.start = *entry;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,47 +145,47 @@ static int fill_create_process_event( struct debug_event *event, const void *arg
|
||||||
|
|
||||||
/* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
|
/* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
|
||||||
if (!(handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, 0 ))) return 0;
|
if (!(handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, 0 ))) return 0;
|
||||||
event->data.info.create_process.process = handle;
|
event->data.create_process.process = handle;
|
||||||
|
|
||||||
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
|
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
|
||||||
if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 )))
|
if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 )))
|
||||||
{
|
{
|
||||||
close_handle( debugger, event->data.info.create_process.process );
|
close_handle( debugger, event->data.create_process.process );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
event->data.info.create_process.thread = handle;
|
event->data.create_process.thread = handle;
|
||||||
|
|
||||||
handle = 0;
|
handle = 0;
|
||||||
if (exe_module->file &&
|
if (exe_module->file &&
|
||||||
/* the doc says write access too, but this doesn't seem a good idea */
|
/* the doc says write access too, but this doesn't seem a good idea */
|
||||||
!(handle = alloc_handle( debugger, exe_module->file, GENERIC_READ, 0 )))
|
!(handle = alloc_handle( debugger, exe_module->file, GENERIC_READ, 0 )))
|
||||||
{
|
{
|
||||||
close_handle( debugger, event->data.info.create_process.process );
|
close_handle( debugger, event->data.create_process.process );
|
||||||
close_handle( debugger, event->data.info.create_process.thread );
|
close_handle( debugger, event->data.create_process.thread );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
event->data.info.create_process.file = handle;
|
event->data.create_process.file = handle;
|
||||||
event->data.info.create_process.teb = thread->teb;
|
event->data.create_process.teb = thread->teb;
|
||||||
event->data.info.create_process.base = exe_module->base;
|
event->data.create_process.base = exe_module->base;
|
||||||
event->data.info.create_process.start = *entry;
|
event->data.create_process.start = *entry;
|
||||||
event->data.info.create_process.dbg_offset = exe_module->dbg_offset;
|
event->data.create_process.dbg_offset = exe_module->dbg_offset;
|
||||||
event->data.info.create_process.dbg_size = exe_module->dbg_size;
|
event->data.create_process.dbg_size = exe_module->dbg_size;
|
||||||
event->data.info.create_process.name = exe_module->name;
|
event->data.create_process.name = exe_module->name;
|
||||||
event->data.info.create_process.unicode = 1;
|
event->data.create_process.unicode = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_exit_thread_event( struct debug_event *event, const void *arg )
|
static int fill_exit_thread_event( struct debug_event *event, const void *arg )
|
||||||
{
|
{
|
||||||
const struct thread *thread = arg;
|
const struct thread *thread = arg;
|
||||||
event->data.info.exit.exit_code = thread->exit_code;
|
event->data.exit.exit_code = thread->exit_code;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_exit_process_event( struct debug_event *event, const void *arg )
|
static int fill_exit_process_event( struct debug_event *event, const void *arg )
|
||||||
{
|
{
|
||||||
const struct process *process = arg;
|
const struct process *process = arg;
|
||||||
event->data.info.exit.exit_code = process->exit_code;
|
event->data.exit.exit_code = process->exit_code;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,26 +197,26 @@ static int fill_load_dll_event( struct debug_event *event, const void *arg )
|
||||||
|
|
||||||
if (dll->file && !(handle = alloc_handle( debugger, dll->file, GENERIC_READ, 0 )))
|
if (dll->file && !(handle = alloc_handle( debugger, dll->file, GENERIC_READ, 0 )))
|
||||||
return 0;
|
return 0;
|
||||||
event->data.info.load_dll.handle = handle;
|
event->data.load_dll.handle = handle;
|
||||||
event->data.info.load_dll.base = dll->base;
|
event->data.load_dll.base = dll->base;
|
||||||
event->data.info.load_dll.dbg_offset = dll->dbg_offset;
|
event->data.load_dll.dbg_offset = dll->dbg_offset;
|
||||||
event->data.info.load_dll.dbg_size = dll->dbg_size;
|
event->data.load_dll.dbg_size = dll->dbg_size;
|
||||||
event->data.info.load_dll.name = dll->name;
|
event->data.load_dll.name = dll->name;
|
||||||
event->data.info.load_dll.unicode = 1;
|
event->data.load_dll.unicode = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_unload_dll_event( struct debug_event *event, const void *arg )
|
static int fill_unload_dll_event( struct debug_event *event, const void *arg )
|
||||||
{
|
{
|
||||||
const mod_handle_t *base = arg;
|
const mod_handle_t *base = arg;
|
||||||
event->data.info.unload_dll.base = *base;
|
event->data.unload_dll.base = *base;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_output_debug_string_event( struct debug_event *event, const void *arg )
|
static int fill_output_debug_string_event( struct debug_event *event, const void *arg )
|
||||||
{
|
{
|
||||||
const struct debug_event_output_string *data = arg;
|
const debug_event_t *data = arg;
|
||||||
event->data.info.output_string = *data;
|
event->data.output_string = data->output_string;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,17 +298,17 @@ static void debug_event_destroy( struct object *obj )
|
||||||
switch(event->data.code)
|
switch(event->data.code)
|
||||||
{
|
{
|
||||||
case CREATE_THREAD_DEBUG_EVENT:
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
close_handle( debugger, event->data.info.create_thread.handle );
|
close_handle( debugger, event->data.create_thread.handle );
|
||||||
break;
|
break;
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
if (event->data.info.create_process.file)
|
if (event->data.create_process.file)
|
||||||
close_handle( debugger, event->data.info.create_process.file );
|
close_handle( debugger, event->data.create_process.file );
|
||||||
close_handle( debugger, event->data.info.create_process.thread );
|
close_handle( debugger, event->data.create_process.thread );
|
||||||
close_handle( debugger, event->data.info.create_process.process );
|
close_handle( debugger, event->data.create_process.process );
|
||||||
break;
|
break;
|
||||||
case LOAD_DLL_DEBUG_EVENT:
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
if (event->data.info.load_dll.handle)
|
if (event->data.load_dll.handle)
|
||||||
close_handle( debugger, event->data.info.load_dll.handle );
|
close_handle( debugger, event->data.load_dll.handle );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,7 +391,6 @@ static struct debug_event *alloc_debug_event( struct thread *thread, int code,
|
||||||
event->sender = (struct thread *)grab_object( thread );
|
event->sender = (struct thread *)grab_object( thread );
|
||||||
event->debugger = (struct thread *)grab_object( debugger );
|
event->debugger = (struct thread *)grab_object( debugger );
|
||||||
memset( &event->data, 0, sizeof(event->data) );
|
memset( &event->data, 0, sizeof(event->data) );
|
||||||
event->data.code = code;
|
|
||||||
|
|
||||||
if (!fill_debug_event[code-1]( event, arg ))
|
if (!fill_debug_event[code-1]( event, arg ))
|
||||||
{
|
{
|
||||||
|
@ -398,6 +398,7 @@ static struct debug_event *alloc_debug_event( struct thread *thread, int code,
|
||||||
release_object( event );
|
release_object( event );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
event->data.code = code;
|
||||||
if (context)
|
if (context)
|
||||||
{
|
{
|
||||||
memcpy( &event->context, context, sizeof(event->context) );
|
memcpy( &event->context, context, sizeof(event->context) );
|
||||||
|
@ -635,7 +636,7 @@ DECL_HANDLER(queue_exception_event)
|
||||||
reply->handle = 0;
|
reply->handle = 0;
|
||||||
if (current->process->debugger)
|
if (current->process->debugger)
|
||||||
{
|
{
|
||||||
struct debug_event_exception data;
|
debug_event_t data;
|
||||||
struct debug_event *event;
|
struct debug_event *event;
|
||||||
const CONTEXT *context = get_req_data();
|
const CONTEXT *context = get_req_data();
|
||||||
const EXCEPTION_RECORD *rec = (const EXCEPTION_RECORD *)(context + 1);
|
const EXCEPTION_RECORD *rec = (const EXCEPTION_RECORD *)(context + 1);
|
||||||
|
@ -645,8 +646,8 @@ DECL_HANDLER(queue_exception_event)
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
set_error( STATUS_INVALID_PARAMETER );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.record = *rec;
|
data.exception.record = *rec;
|
||||||
data.first = req->first;
|
data.exception.first = req->first;
|
||||||
if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context )))
|
if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context )))
|
||||||
{
|
{
|
||||||
if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, 0 )))
|
if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, 0 )))
|
||||||
|
@ -686,11 +687,11 @@ DECL_HANDLER(get_exception_status)
|
||||||
/* send an output string to the debugger */
|
/* send an output string to the debugger */
|
||||||
DECL_HANDLER(output_debug_string)
|
DECL_HANDLER(output_debug_string)
|
||||||
{
|
{
|
||||||
struct debug_event_output_string data;
|
debug_event_t data;
|
||||||
|
|
||||||
data.string = req->string;
|
data.output_string.string = req->string;
|
||||||
data.unicode = req->unicode;
|
data.output_string.unicode = req->unicode;
|
||||||
data.length = req->length;
|
data.output_string.length = req->length;
|
||||||
generate_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, &data );
|
generate_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, &data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,20 +69,26 @@ struct request_max_size
|
||||||
#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
|
#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
|
||||||
|
|
||||||
|
|
||||||
/* definitions of the event data depending on the event code */
|
/* debug event data */
|
||||||
struct debug_event_exception
|
typedef union
|
||||||
{
|
{
|
||||||
EXCEPTION_RECORD record; /* exception record */
|
int code; /* event code */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int code; /* EXCEPTION_DEBUG_EVENT */
|
||||||
int first; /* first chance exception? */
|
int first; /* first chance exception? */
|
||||||
};
|
EXCEPTION_RECORD record; /* exception record */
|
||||||
struct debug_event_create_thread
|
} exception;
|
||||||
{
|
struct
|
||||||
|
{
|
||||||
|
int code; /* CREATE_THREAD_DEBUG_EVENT */
|
||||||
obj_handle_t handle; /* handle to the new thread */
|
obj_handle_t handle; /* handle to the new thread */
|
||||||
client_ptr_t teb; /* thread teb (in debugged process address space) */
|
client_ptr_t teb; /* thread teb (in debugged process address space) */
|
||||||
client_ptr_t start; /* thread startup routine */
|
client_ptr_t start; /* thread startup routine */
|
||||||
};
|
} create_thread;
|
||||||
struct debug_event_create_process
|
struct
|
||||||
{
|
{
|
||||||
|
int code; /* CREATE_PROCESS_DEBUG_EVENT */
|
||||||
obj_handle_t file; /* handle to the process exe file */
|
obj_handle_t file; /* handle to the process exe file */
|
||||||
obj_handle_t process; /* handle to the new process */
|
obj_handle_t process; /* handle to the new process */
|
||||||
obj_handle_t thread; /* handle to the new thread */
|
obj_handle_t thread; /* handle to the new thread */
|
||||||
|
@ -93,52 +99,41 @@ struct debug_event_create_process
|
||||||
client_ptr_t start; /* thread startup routine */
|
client_ptr_t start; /* thread startup routine */
|
||||||
client_ptr_t name; /* image name (optional) */
|
client_ptr_t name; /* image name (optional) */
|
||||||
int unicode; /* is it Unicode? */
|
int unicode; /* is it Unicode? */
|
||||||
};
|
} create_process;
|
||||||
struct debug_event_exit
|
struct
|
||||||
{
|
{
|
||||||
|
int code; /* EXIT_THREAD_DEBUG_EVENT/EXIT_PROCESS_DEBUG_EVENT */
|
||||||
int exit_code; /* thread or process exit code */
|
int exit_code; /* thread or process exit code */
|
||||||
};
|
} exit;
|
||||||
struct debug_event_load_dll
|
struct
|
||||||
{
|
{
|
||||||
|
int code; /* LOAD_DLL_DEBUG_EVENT */
|
||||||
obj_handle_t handle; /* file handle for the dll */
|
obj_handle_t handle; /* file handle for the dll */
|
||||||
mod_handle_t base; /* base address of the dll */
|
mod_handle_t base; /* base address of the dll */
|
||||||
int dbg_offset; /* offset of debug info in file */
|
int dbg_offset; /* offset of debug info in file */
|
||||||
int dbg_size; /* size of debug info */
|
int dbg_size; /* size of debug info */
|
||||||
client_ptr_t name; /* image name (optional) */
|
client_ptr_t name; /* image name (optional) */
|
||||||
int unicode; /* is it Unicode? */
|
int unicode; /* is it Unicode? */
|
||||||
};
|
} load_dll;
|
||||||
struct debug_event_unload_dll
|
struct
|
||||||
{
|
{
|
||||||
|
int code; /* UNLOAD_DLL_DEBUG_EVENT */
|
||||||
|
int __pad;
|
||||||
mod_handle_t base; /* base address of the dll */
|
mod_handle_t base; /* base address of the dll */
|
||||||
};
|
} unload_dll;
|
||||||
struct debug_event_output_string
|
struct
|
||||||
{
|
{
|
||||||
client_ptr_t string; /* string to display (in debugged process address space) */
|
int code; /* OUTPUT_DEBUG_STRING_EVENT */
|
||||||
int unicode; /* is it Unicode? */
|
int unicode; /* is it Unicode? */
|
||||||
|
client_ptr_t string; /* string to display (in debugged process address space) */
|
||||||
data_size_t length; /* string length */
|
data_size_t length; /* string length */
|
||||||
};
|
} output_string;
|
||||||
struct debug_event_rip_info
|
struct
|
||||||
{
|
{
|
||||||
|
int code; /* RIP_EVENT */
|
||||||
int error; /* ??? */
|
int error; /* ??? */
|
||||||
int type; /* ??? */
|
int type; /* ??? */
|
||||||
};
|
} rip_info;
|
||||||
union debug_event_data
|
|
||||||
{
|
|
||||||
struct debug_event_exception exception;
|
|
||||||
struct debug_event_create_thread create_thread;
|
|
||||||
struct debug_event_create_process create_process;
|
|
||||||
struct debug_event_exit exit;
|
|
||||||
struct debug_event_load_dll load_dll;
|
|
||||||
struct debug_event_unload_dll unload_dll;
|
|
||||||
struct debug_event_output_string output_string;
|
|
||||||
struct debug_event_rip_info rip_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* debug event data */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int code; /* event code */
|
|
||||||
union debug_event_data info; /* event information */
|
|
||||||
} debug_event_t;
|
} debug_event_t;
|
||||||
|
|
||||||
/* structure used in sending an fd from client to server */
|
/* structure used in sending an fd from client to server */
|
||||||
|
|
|
@ -932,16 +932,16 @@ void kill_thread( struct thread *thread, int violent_death )
|
||||||
/* trigger a breakpoint event in a given thread */
|
/* trigger a breakpoint event in a given thread */
|
||||||
void break_thread( struct thread *thread )
|
void break_thread( struct thread *thread )
|
||||||
{
|
{
|
||||||
struct debug_event_exception data;
|
debug_event_t data;
|
||||||
|
|
||||||
assert( thread->context );
|
assert( thread->context );
|
||||||
|
|
||||||
data.record.ExceptionCode = STATUS_BREAKPOINT;
|
data.exception.record.ExceptionCode = STATUS_BREAKPOINT;
|
||||||
data.record.ExceptionFlags = EXCEPTION_CONTINUABLE;
|
data.exception.record.ExceptionFlags = EXCEPTION_CONTINUABLE;
|
||||||
data.record.ExceptionRecord = NULL;
|
data.exception.record.ExceptionRecord = NULL;
|
||||||
data.record.ExceptionAddress = get_context_ip( thread->context );
|
data.exception.record.ExceptionAddress = get_context_ip( thread->context );
|
||||||
data.record.NumberParameters = 0;
|
data.exception.record.NumberParameters = 0;
|
||||||
data.first = 1;
|
data.exception.first = 1;
|
||||||
generate_debug_event( thread, EXCEPTION_DEBUG_EVENT, &data );
|
generate_debug_event( thread, EXCEPTION_DEBUG_EVENT, &data );
|
||||||
thread->debug_break = 0;
|
thread->debug_break = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,58 +495,58 @@ static void dump_varargs_debug_event( data_size_t size )
|
||||||
{
|
{
|
||||||
case EXCEPTION_DEBUG_EVENT:
|
case EXCEPTION_DEBUG_EVENT:
|
||||||
fprintf( stderr, "{exception," );
|
fprintf( stderr, "{exception," );
|
||||||
dump_exc_record( &event->info.exception.record );
|
dump_exc_record( &event->exception.record );
|
||||||
fprintf( stderr, ",first=%d}", event->info.exception.first );
|
fprintf( stderr, ",first=%d}", event->exception.first );
|
||||||
break;
|
break;
|
||||||
case CREATE_THREAD_DEBUG_EVENT:
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
fprintf( stderr, "{create_thread,thread=%04x,teb=", event->info.create_thread.handle );
|
fprintf( stderr, "{create_thread,thread=%04x,teb=", event->create_thread.handle );
|
||||||
dump_uint64( &event->info.create_thread.teb );
|
dump_uint64( &event->create_thread.teb );
|
||||||
fprintf( stderr, ",start=" );
|
fprintf( stderr, ",start=" );
|
||||||
dump_uint64( &event->info.create_thread.start );
|
dump_uint64( &event->create_thread.start );
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
break;
|
break;
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
fprintf( stderr, "{create_process,file=%04x,process=%04x,thread=%04x,base=",
|
fprintf( stderr, "{create_process,file=%04x,process=%04x,thread=%04x,base=",
|
||||||
event->info.create_process.file, event->info.create_process.process,
|
event->create_process.file, event->create_process.process,
|
||||||
event->info.create_process.thread );
|
event->create_process.thread );
|
||||||
dump_uint64( &event->info.create_process.base );
|
dump_uint64( &event->create_process.base );
|
||||||
fprintf( stderr, ",offset=%d,size=%d,teb=",
|
fprintf( stderr, ",offset=%d,size=%d,teb=",
|
||||||
event->info.create_process.dbg_offset, event->info.create_process.dbg_size );
|
event->create_process.dbg_offset, event->create_process.dbg_size );
|
||||||
dump_uint64( &event->info.create_process.teb );
|
dump_uint64( &event->create_process.teb );
|
||||||
fprintf( stderr, ",start=" );
|
fprintf( stderr, ",start=" );
|
||||||
dump_uint64( &event->info.create_process.start );
|
dump_uint64( &event->create_process.start );
|
||||||
fprintf( stderr, ",name=" );
|
fprintf( stderr, ",name=" );
|
||||||
dump_uint64( &event->info.create_process.name );
|
dump_uint64( &event->create_process.name );
|
||||||
fprintf( stderr, ",unicode=%d}", event->info.create_process.unicode );
|
fprintf( stderr, ",unicode=%d}", event->create_process.unicode );
|
||||||
break;
|
break;
|
||||||
case EXIT_THREAD_DEBUG_EVENT:
|
case EXIT_THREAD_DEBUG_EVENT:
|
||||||
fprintf( stderr, "{exit_thread,code=%d}", event->info.exit.exit_code );
|
fprintf( stderr, "{exit_thread,code=%d}", event->exit.exit_code );
|
||||||
break;
|
break;
|
||||||
case EXIT_PROCESS_DEBUG_EVENT:
|
case EXIT_PROCESS_DEBUG_EVENT:
|
||||||
fprintf( stderr, "{exit_process,code=%d}", event->info.exit.exit_code );
|
fprintf( stderr, "{exit_process,code=%d}", event->exit.exit_code );
|
||||||
break;
|
break;
|
||||||
case LOAD_DLL_DEBUG_EVENT:
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
fprintf( stderr, "{load_dll,file=%04x,base", event->info.load_dll.handle );
|
fprintf( stderr, "{load_dll,file=%04x,base", event->load_dll.handle );
|
||||||
dump_uint64( &event->info.load_dll.base );
|
dump_uint64( &event->load_dll.base );
|
||||||
fprintf( stderr, ",offset=%d,size=%d,name=",
|
fprintf( stderr, ",offset=%d,size=%d,name=",
|
||||||
event->info.load_dll.dbg_offset, event->info.load_dll.dbg_size );
|
event->load_dll.dbg_offset, event->load_dll.dbg_size );
|
||||||
dump_uint64( &event->info.load_dll.name );
|
dump_uint64( &event->load_dll.name );
|
||||||
fprintf( stderr, ",unicode=%d}", event->info.load_dll.unicode );
|
fprintf( stderr, ",unicode=%d}", event->load_dll.unicode );
|
||||||
break;
|
break;
|
||||||
case UNLOAD_DLL_DEBUG_EVENT:
|
case UNLOAD_DLL_DEBUG_EVENT:
|
||||||
fputs( "{unload_dll,base=", stderr );
|
fputs( "{unload_dll,base=", stderr );
|
||||||
dump_uint64( &event->info.unload_dll.base );
|
dump_uint64( &event->unload_dll.base );
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
break;
|
break;
|
||||||
case OUTPUT_DEBUG_STRING_EVENT:
|
case OUTPUT_DEBUG_STRING_EVENT:
|
||||||
fprintf( stderr, "{output_string,string=" );
|
fprintf( stderr, "{output_string,string=" );
|
||||||
dump_uint64( &event->info.output_string.string );
|
dump_uint64( &event->output_string.string );
|
||||||
fprintf( stderr, ",unicode=%d,len=%u}",
|
fprintf( stderr, ",unicode=%d,len=%u}",
|
||||||
event->info.output_string.unicode, event->info.output_string.length );
|
event->output_string.unicode, event->output_string.length );
|
||||||
break;
|
break;
|
||||||
case RIP_EVENT:
|
case RIP_EVENT:
|
||||||
fprintf( stderr, "{rip,err=%d,type=%d}",
|
fprintf( stderr, "{rip,err=%d,type=%d}",
|
||||||
event->info.rip_info.error, event->info.rip_info.type );
|
event->rip_info.error, event->rip_info.type );
|
||||||
break;
|
break;
|
||||||
case 0: /* zero is the code returned on timeouts */
|
case 0: /* zero is the code returned on timeouts */
|
||||||
fprintf( stderr, "{}" );
|
fprintf( stderr, "{}" );
|
||||||
|
|
Loading…
Reference in New Issue