Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
6159431c
Commit
6159431c
authored
Jul 30, 2018
by
Zebediah Figura
Committed by
Alexandre Julliard
Aug 16, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedbg/gdbproxy: Use the WINEDEBUG interface for debugging winedbg.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2a28db37
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
78 additions
and
204 deletions
+78
-204
gdbproxy.c
programs/winedbg/gdbproxy.c
+78
-204
No files found.
programs/winedbg/gdbproxy.c
View file @
6159431c
...
...
@@ -63,14 +63,9 @@
#include "windef.h"
#include "winbase.h"
#include "tlhelp32.h"
#include "wine/debug.h"
#define GDBPXY_TRC_LOWLEVEL 0x01
#define GDBPXY_TRC_PACKET 0x02
#define GDBPXY_TRC_COMMAND 0x04
#define GDBPXY_TRC_COMMAND_ERROR 0x08
#define GDBPXY_TRC_WIN32_EVENT 0x10
#define GDBPXY_TRC_WIN32_ERROR 0x20
#define GDBPXY_TRC_COMMAND_FIXME 0x80
WINE_DEFAULT_DEBUG_CHANNEL
(
winedbg
);
struct
gdb_context
{
...
...
@@ -91,7 +86,6 @@ struct gdb_context
/* generic GDB thread information */
struct
dbg_thread
*
exec_thread
;
/* thread used in step & continue */
struct
dbg_thread
*
other_thread
;
/* thread to be used in any other operation */
unsigned
trace
;
/* current Win32 trap env */
unsigned
last_sig
;
BOOL
in_trap
;
...
...
@@ -234,7 +228,7 @@ static inline DWORD64 cpu_register(struct gdb_context *gdbctx,
case
4
:
return
*
(
DWORD
*
)
cpu_register_ptr
(
gdbctx
,
ctx
,
idx
);
case
8
:
return
*
(
DWORD64
*
)
cpu_register_ptr
(
gdbctx
,
ctx
,
idx
);
default:
fprintf
(
stderr
,
"got unexpected size: %u
\n
"
,
ERR
(
"got unexpected size: %u
\n
"
,
(
unsigned
)
gdbctx
->
process
->
be_cpu
->
gdb_register_map
[
idx
].
ctx_length
);
assert
(
0
);
return
0
;
...
...
@@ -280,8 +274,7 @@ static BOOL fetch_context(struct gdb_context *gdbctx, HANDLE h, dbg_ctx_t *ctx)
{
if
(
!
gdbctx
->
process
->
be_cpu
->
get_context
(
h
,
ctx
))
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Can't get thread's context
\n
"
);
ERR
(
"Failed to get context, error %u
\n
"
,
GetLastError
());
return
FALSE
;
}
return
TRUE
;
...
...
@@ -360,11 +353,10 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e
}
}
else
fprintf
(
stderr
,
"Cannot set name of thread %04x
\n
"
,
threadname
->
dwThreadID
);
ERR
(
"Cannot set name of thread %04x
\n
"
,
threadname
->
dwThreadID
);
return
DBG_CONTINUE
;
}
default:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"Unhandled exception code 0x%08x
\n
"
,
rec
->
ExceptionCode
);
gdbctx
->
last_sig
=
SIGABRT
;
ret
=
TRUE
;
...
...
@@ -394,7 +386,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
u
.
buffer
,
ARRAY_SIZE
(
u
.
buffer
));
dbg_set_process_name
(
gdbctx
->
process
,
u
.
buffer
);
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%04x:%04x: create process '%s'/%p @%p (%u<%u>)
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
dbg_W2A
(
u
.
buffer
,
-
1
),
...
...
@@ -405,12 +396,10 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
/* de->u.CreateProcessInfo.lpStartAddress; */
if
(
!
dbg_init
(
gdbctx
->
process
->
handle
,
u
.
buffer
,
TRUE
))
fprintf
(
stderr
,
"Couldn't initiate DbgHelp
\n
"
);
ERR
(
"Couldn't initiate DbgHelp
\n
"
);
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%04x:%04x: create thread I @%p
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
CreateProcessInfo
.
lpStartAddress
);
fprintf
(
stderr
,
"%04x:%04x: create thread I @%p
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
CreateProcessInfo
.
lpStartAddress
);
assert
(
dbg_curr_thread
==
NULL
);
/* shouldn't be there */
dbg_add_thread
(
gdbctx
->
process
,
de
->
dwThreadId
,
...
...
@@ -424,7 +413,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
de
->
u
.
LoadDll
.
lpImageName
,
de
->
u
.
LoadDll
.
fUnicode
,
u
.
buffer
,
ARRAY_SIZE
(
u
.
buffer
));
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%04x:%04x: loads DLL %s @%p (%u<%u>)
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
dbg_W2A
(
u
.
buffer
,
-
1
),
...
...
@@ -436,7 +424,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
break
;
case
UNLOAD_DLL_DEBUG_EVENT
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: unload DLL @%p
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
UnloadDll
.
lpBaseOfDll
);
SymUnloadModule
(
gdbctx
->
process
->
handle
,
...
...
@@ -445,10 +432,8 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
case
EXCEPTION_DEBUG_EVENT
:
assert
(
dbg_curr_thread
);
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: exception code=0x%08x
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
);
fprintf
(
stderr
,
"%08x:%08x: exception code=0x%08x
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
);
if
(
fetch_context
(
gdbctx
,
dbg_curr_thread
->
handle
,
&
gdbctx
->
context
))
{
...
...
@@ -457,9 +442,8 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
break
;
case
CREATE_THREAD_DEBUG_EVENT
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: create thread D @%p
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
CreateThread
.
lpStartAddress
);
fprintf
(
stderr
,
"%08x:%08x: create thread D @%p
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
CreateThread
.
lpStartAddress
);
dbg_add_thread
(
gdbctx
->
process
,
de
->
dwThreadId
,
...
...
@@ -468,7 +452,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
break
;
case
EXIT_THREAD_DEBUG_EVENT
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: exit thread (%u)
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
ExitThread
.
dwExitCode
);
...
...
@@ -479,7 +462,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
break
;
case
EXIT_PROCESS_DEBUG_EVENT
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: exit process (%u)
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
ExitProcess
.
dwExitCode
);
...
...
@@ -495,21 +477,17 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
memory_get_string
(
gdbctx
->
process
,
de
->
u
.
DebugString
.
lpDebugStringData
,
TRUE
,
de
->
u
.
DebugString
.
fUnicode
,
u
.
bufferA
,
sizeof
(
u
.
bufferA
));
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: output debug string (%s)
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
u
.
bufferA
);
de
->
dwProcessId
,
de
->
dwThreadId
,
debugstr_a
(
u
.
bufferA
)
);
break
;
case
RIP_EVENT
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: rip error=%u type=%u
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
RipInfo
.
dwError
,
de
->
u
.
RipInfo
.
dwType
);
fprintf
(
stderr
,
"%08x:%08x: rip error=%u type=%u
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
u
.
RipInfo
.
dwError
,
de
->
u
.
RipInfo
.
dwType
);
break
;
default:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_EVENT
)
fprintf
(
stderr
,
"%08x:%08x: unknown event (%u)
\n
"
,
FIXME
(
"%08x:%08x: unknown event (%u)
\n
"
,
de
->
dwProcessId
,
de
->
dwThreadId
,
de
->
dwDebugEventCode
);
}
}
...
...
@@ -519,15 +497,14 @@ static void resume_debuggee(struct gdb_context* gdbctx, DWORD cont)
if
(
dbg_curr_thread
)
{
if
(
!
gdbctx
->
process
->
be_cpu
->
set_context
(
dbg_curr_thread
->
handle
,
&
gdbctx
->
context
))
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot set context on thread %04x
\n
"
,
dbg_curr_thread
->
tid
);
ERR
(
"Failed to set context for thread %04x, error %u
\n
"
,
dbg_curr_thread
->
tid
,
GetLastError
()
);
if
(
!
ContinueDebugEvent
(
gdbctx
->
process
->
pid
,
dbg_curr_thread
->
tid
,
cont
))
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot continue on %04x (%x)
\n
"
,
dbg_curr_thread
->
tid
,
cont
);
ERR
(
"Failed to continue thread %04x, error %u
\n
"
,
dbg_curr_thread
->
tid
,
GetLastError
());
}
else
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot find last thread
\n
"
);
else
ERR
(
"Cannot find last thread
\n
"
);
}
...
...
@@ -539,16 +516,15 @@ static void resume_debuggee_thread(struct gdb_context* gdbctx, DWORD cont, unsig
if
(
dbg_curr_thread
->
tid
==
threadid
){
/* Windows debug and GDB don't seem to work well here, windows only likes ContinueDebugEvent being used on the reporter of the event */
if
(
!
gdbctx
->
process
->
be_cpu
->
set_context
(
dbg_curr_thread
->
handle
,
&
gdbctx
->
context
))
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot set context on thread %04x
\n
"
,
dbg_curr_thread
->
tid
);
ERR
(
"Failed to set context for thread %04x, error %u
\n
"
,
dbg_curr_thread
->
tid
,
GetLastError
()
);
if
(
!
ContinueDebugEvent
(
gdbctx
->
process
->
pid
,
dbg_curr_thread
->
tid
,
cont
))
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot continue on %04x (%x)
\n
"
,
dbg_curr_thread
->
tid
,
cont
);
ERR
(
"Failed to continue thread %04x, error %u
\n
"
,
dbg_curr_thread
->
tid
,
GetLastError
());
}
}
else
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot find last thread
\n
"
);
else
ERR
(
"Cannot find last thread
\n
"
);
}
static
BOOL
check_for_interrupt
(
struct
gdb_context
*
gdbctx
)
...
...
@@ -564,20 +540,16 @@ static BOOL check_for_interrupt(struct gdb_context* gdbctx)
if
((
ret
=
poll
(
&
pollfd
,
1
,
0
))
==
1
)
{
ret
=
read
(
gdbctx
->
sock
,
&
pkt
,
1
);
if
(
ret
!=
1
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
{
fprintf
(
stderr
,
"read failed
\n
"
);
}
ERR
(
"read failed
\n
"
);
return
FALSE
;
}
if
(
pkt
!=
'\003'
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
{
fprintf
(
stderr
,
"Unexpected break packet (%c/0x%X)
\n
"
,
pkt
,
pkt
);
}
ERR
(
"Unexpected break packet %#02x
\n
"
,
pkt
);
return
FALSE
;
}
return
TRUE
;
}
else
if
(
ret
==
-
1
)
{
fprintf
(
stderr
,
"poll failed
\n
"
);
ERR
(
"poll failed
\n
"
);
}
return
FALSE
;
}
...
...
@@ -595,9 +567,7 @@ static void wait_for_debuggee(struct gdb_context* gdbctx)
{
if
(
check_for_interrupt
(
gdbctx
))
{
if
(
!
DebugBreakProcess
(
gdbctx
->
process
->
handle
))
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
{
fprintf
(
stderr
,
"Failed to break into debugee
\n
"
);
}
ERR
(
"Failed to break into debugee
\n
"
);
break
;
}
WaitForDebugEvent
(
&
de
,
INFINITE
);
...
...
@@ -794,9 +764,6 @@ static void packet_reply_close(struct gdb_context* gdbctx)
packet_reply_catc
(
gdbctx
,
'#'
);
cksum
=
checksum
(
&
gdbctx
->
out_buf
[
gdbctx
->
out_curr_packet
],
plen
);
packet_reply_hex_to
(
gdbctx
,
&
cksum
,
1
);
if
(
gdbctx
->
trace
&
GDBPXY_TRC_PACKET
)
fprintf
(
stderr
,
"Reply : %*.*s
\n
"
,
plen
,
plen
,
&
gdbctx
->
out_buf
[
gdbctx
->
out_curr_packet
]);
gdbctx
->
out_curr_packet
=
-
1
;
}
...
...
@@ -914,8 +881,7 @@ static enum packet_return packet_continue(struct gdb_context* gdbctx)
/* FIXME: add support for address in packet */
assert
(
gdbctx
->
in_packet_len
==
0
);
if
(
dbg_curr_thread
!=
gdbctx
->
exec_thread
&&
gdbctx
->
exec_thread
)
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_FIXME
)
fprintf
(
stderr
,
"NIY: cont on %04x, while last thread is %04x
\n
"
,
FIXME
(
"Can't continue thread %04x while on thread %04x
\n
"
,
gdbctx
->
exec_thread
->
tid
,
dbg_curr_thread
->
tid
);
resume_debuggee
(
gdbctx
,
DBG_CONTINUE
);
wait_for_debuggee
(
gdbctx
);
...
...
@@ -965,13 +931,6 @@ static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
return
packet_done
;
}
/* This may not be the 'fastest' code in the world. but it should be nice and easy to debug.
(as it's run when people are debugging break points I'm sure they won't notice the extra 100 cycles anyway)
now if only gdb talked XML.... */
#if 0 /* handy for debugging */
fprintf(stderr, "no, but can we find a default packet %.*s %d\n", gdbctx->in_packet_len, gdbctx->in_packet, gdbctx->in_packet_len);
#endif
/* go through the packet and identify where all the actions start at */
for
(
i
=
4
;
i
<
gdbctx
->
in_packet_len
-
1
;
i
++
)
{
...
...
@@ -1019,8 +978,7 @@ static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
* that remains is to apply the actions to the threads and the default action to any threads
* left */
if
(
dbg_curr_thread
!=
gdbctx
->
exec_thread
&&
gdbctx
->
exec_thread
)
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_FIXME
)
fprintf
(
stderr
,
"NIY: cont on %04x, while last thread is %04x
\n
"
,
FIXME
(
"Can't continue thread %04x while on thread %04x
\n
"
,
gdbctx
->
exec_thread
->
tid
,
dbg_curr_thread
->
tid
);
/* deal with the threaded stuff first */
...
...
@@ -1054,8 +1012,7 @@ static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
case
'C'
:
/* continue sig */
hex_from
(
&
sig
,
gdbctx
->
in_packet
+
actionIndex
[
i
]
+
2
,
1
);
/* cannot change signals on the fly */
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
fprintf
(
stderr
,
"sigs: %u %u
\n
"
,
sig
,
gdbctx
->
last_sig
);
TRACE
(
"sigs: %u %u
\n
"
,
sig
,
gdbctx
->
last_sig
);
if
(
sig
!=
gdbctx
->
last_sig
)
return
packet_error
;
resume_debuggee_thread
(
gdbctx
,
DBG_EXCEPTION_NOT_HANDLED
,
threadID
);
...
...
@@ -1097,8 +1054,7 @@ static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
case
'C'
:
/* continue sig */
hex_from
(
&
sig
,
gdbctx
->
in_packet
+
actionIndex
[
defaultAction
]
+
2
,
1
);
/* cannot change signals on the fly */
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
fprintf
(
stderr
,
"sigs: %u %u
\n
"
,
sig
,
gdbctx
->
last_sig
);
TRACE
(
"sigs: %u %u
\n
"
,
sig
,
gdbctx
->
last_sig
);
if
(
sig
!=
gdbctx
->
last_sig
)
return
packet_error
;
resume_debuggee_thread
(
gdbctx
,
DBG_EXCEPTION_NOT_HANDLED
,
threadID
);
...
...
@@ -1143,9 +1099,8 @@ static enum packet_return packet_verbose(struct gdb_context* gdbctx)
gdbctx
->
in_packet
[
klen
]
==
':'
||
gdbctx
->
in_packet
[
klen
]
==
'?'
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
fprintf
(
stderr
,
"trying to process a verbose packet %*.*s
\n
"
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet
);
TRACE
(
"Trying to process verbose packet %s
\n
"
,
debugstr_an
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
));
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
verbose_details
);
i
++
)
{
if
(
klen
==
verbose_details
[
i
].
len
&&
...
...
@@ -1159,9 +1114,8 @@ static enum packet_return packet_verbose(struct gdb_context* gdbctx)
}
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_FIXME
)
fprintf
(
stderr
,
"No support for verbose packet %*.*s
\n
"
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet
);
WARN
(
"No support for verbose packet %s
\n
"
,
debugstr_an
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
));
return
packet_error
;
}
...
...
@@ -1172,13 +1126,11 @@ static enum packet_return packet_continue_signal(struct gdb_context* gdbctx)
/* FIXME: add support for address in packet */
assert
(
gdbctx
->
in_packet_len
==
2
);
if
(
dbg_curr_thread
!=
gdbctx
->
exec_thread
&&
gdbctx
->
exec_thread
)
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_FIXME
)
fprintf
(
stderr
,
"NIY: cont/sig on %04x, while last thread is %04x
\n
"
,
FIXME
(
"Can't continue thread %04x while on thread %04x
\n
"
,
gdbctx
->
exec_thread
->
tid
,
dbg_curr_thread
->
tid
);
hex_from
(
&
sig
,
gdbctx
->
in_packet
,
1
);
/* cannot change signals on the fly */
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
fprintf
(
stderr
,
"sigs: %u %u
\n
"
,
sig
,
gdbctx
->
last_sig
);
TRACE
(
"sigs: %u %u
\n
"
,
sig
,
gdbctx
->
last_sig
);
if
(
sig
!=
gdbctx
->
last_sig
)
return
packet_error
;
resume_debuggee
(
gdbctx
,
DBG_EXCEPTION_NOT_HANDLED
);
...
...
@@ -1236,8 +1188,8 @@ static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
if
(
pctx
!=
&
gdbctx
->
context
&&
!
gdbctx
->
process
->
be_cpu
->
set_context
(
gdbctx
->
other_thread
->
handle
,
pctx
))
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot set context on thread %04x
\n
"
,
gdbctx
->
other_thread
->
tid
);
ERR
(
"Failed to set context for tid %04x, error %u
\n
"
,
gdbctx
->
other_thread
->
tid
,
GetLastError
()
);
return
packet_error
;
}
return
packet_ok
;
...
...
@@ -1271,10 +1223,8 @@ static enum packet_return packet_thread(struct gdb_context* gdbctx)
thread
=
strtol
(
gdbctx
->
in_packet
+
1
,
&
end
,
16
);
if
(
end
==
NULL
||
end
>
gdbctx
->
in_packet
+
gdbctx
->
in_packet_len
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Cannot get threadid %*.*s
\n
"
,
gdbctx
->
in_packet_len
-
1
,
gdbctx
->
in_packet_len
-
1
,
gdbctx
->
in_packet
+
1
);
ERR
(
"Failed to parse %s
\n
"
,
debugstr_an
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
));
return
packet_error
;
}
if
(
gdbctx
->
in_packet
[
0
]
==
'c'
)
...
...
@@ -1283,8 +1233,7 @@ static enum packet_return packet_thread(struct gdb_context* gdbctx)
gdbctx
->
other_thread
=
dbg_get_thread
(
gdbctx
->
process
,
thread
);
return
packet_ok
;
default:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Unknown thread sub-command %c
\n
"
,
gdbctx
->
in_packet
[
0
]);
FIXME
(
"Unknown thread sub-command %c
\n
"
,
gdbctx
->
in_packet
[
0
]);
return
packet_error
;
}
}
...
...
@@ -1300,8 +1249,7 @@ static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
/* FIXME:check in_packet_len for reading %p,%x */
if
(
sscanf
(
gdbctx
->
in_packet
,
"%p,%x"
,
&
addr
,
&
len
)
!=
2
)
return
packet_error
;
if
(
len
<=
0
)
return
packet_error
;
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
fprintf
(
stderr
,
"Read mem at %p for %u bytes
\n
"
,
addr
,
len
);
TRACE
(
"Read %u bytes at %p
\n
"
,
len
,
addr
);
for
(
nread
=
0
;
nread
<
len
;
nread
+=
r
,
addr
+=
r
)
{
blk_len
=
min
(
sizeof
(
buffer
),
len
-
nread
);
...
...
@@ -1332,28 +1280,23 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
ptr
=
memchr
(
gdbctx
->
in_packet
,
':'
,
gdbctx
->
in_packet_len
);
if
(
ptr
==
NULL
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Cannot find ':' in %*.*s
\n
"
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet
);
ERR
(
"Cannot find ':' in %s
\n
"
,
debugstr_an
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
));
return
packet_error
;
}
*
ptr
++
=
'\0'
;
if
(
sscanf
(
gdbctx
->
in_packet
,
"%p,%x"
,
&
addr
,
&
len
)
!=
2
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Cannot scan addr,len in %s
\n
"
,
gdbctx
->
in_packet
);
ERR
(
"Failed to parse %s
\n
"
,
debugstr_a
(
gdbctx
->
in_packet
));
return
packet_error
;
}
if
(
ptr
-
gdbctx
->
in_packet
+
len
*
2
!=
gdbctx
->
in_packet_len
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Wrong sizes %u <> %u
\n
"
,
ERR
(
"Length %u does not match packet length %u
\n
"
,
(
int
)(
ptr
-
gdbctx
->
in_packet
)
+
len
*
2
,
gdbctx
->
in_packet_len
);
return
packet_error
;
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
fprintf
(
stderr
,
"Write %u bytes at %p
\n
"
,
len
,
addr
);
TRACE
(
"Write %u bytes at %p
\n
"
,
len
,
addr
);
while
(
len
>
0
)
{
blk_len
=
min
(
sizeof
(
buffer
),
len
);
...
...
@@ -1378,8 +1321,7 @@ static enum packet_return packet_read_register(struct gdb_context* gdbctx)
reg
=
hex_to_int
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
);
if
(
reg
>=
gdbctx
->
process
->
be_cpu
->
gdb_num_regs
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Register out of bounds %x
\n
"
,
reg
);
FIXME
(
"Unhandled register %u
\n
"
,
reg
);
return
packet_error
;
}
if
(
dbg_curr_thread
!=
gdbctx
->
other_thread
&&
gdbctx
->
other_thread
)
...
...
@@ -1387,14 +1329,9 @@ static enum packet_return packet_read_register(struct gdb_context* gdbctx)
if
(
!
fetch_context
(
gdbctx
,
gdbctx
->
other_thread
->
handle
,
pctx
=
&
ctx
))
return
packet_error
;
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
{
if
(
gdbctx
->
process
->
be_cpu
->
gdb_register_map
[
reg
].
ctx_length
<=
sizeof
(
DWORD64
))
fprintf
(
stderr
,
"Read register %x => %08x%08x
\n
"
,
reg
,
(
unsigned
)(
cpu_register
(
gdbctx
,
pctx
,
reg
)
>>
32
),
(
unsigned
)
cpu_register
(
gdbctx
,
pctx
,
reg
));
else
fprintf
(
stderr
,
"Read register %x
\n
"
,
reg
);
}
TRACE
(
"%u => %s
\n
"
,
reg
,
wine_dbgstr_longlong
(
cpu_register
(
gdbctx
,
pctx
,
reg
)));
packet_reply_open
(
gdbctx
);
packet_reply_register_hex_to
(
gdbctx
,
reg
);
packet_reply_close
(
gdbctx
);
...
...
@@ -1413,18 +1350,16 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
reg
=
strtoul
(
gdbctx
->
in_packet
,
&
ptr
,
16
);
if
(
ptr
==
NULL
||
reg
>=
gdbctx
->
process
->
be_cpu
->
gdb_num_regs
||
*
ptr
++
!=
'='
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Invalid register index %s
\n
"
,
gdbctx
->
in_packet
);
FIXME
(
"Unhandled register %s
\n
"
,
debugstr_an
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
)
);
/* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
* it wouldn't matter too much, and it fakes our support for all regs
*/
return
(
ptr
==
NULL
)
?
packet_error
:
packet_ok
;
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND
)
{
int
len
=
gdbctx
->
in_packet_len
-
(
ptr
-
gdbctx
->
in_packet
);
fprintf
(
stderr
,
"Writing reg %u <= %*.*s
\n
"
,
reg
,
len
,
len
,
ptr
);
}
TRACE
(
"%u <= %s
\n
"
,
reg
,
debugstr_an
(
ptr
,
(
int
)(
gdbctx
->
in_packet_len
-
(
ptr
-
gdbctx
->
in_packet
))));
if
(
dbg_curr_thread
!=
gdbctx
->
other_thread
&&
gdbctx
->
other_thread
)
{
...
...
@@ -1436,8 +1371,8 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
if
(
pctx
!=
&
gdbctx
->
context
&&
!
gdbctx
->
process
->
be_cpu
->
set_context
(
gdbctx
->
other_thread
->
handle
,
pctx
))
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot set context for thread %04x
\n
"
,
gdbctx
->
other_thread
->
tid
);
ERR
(
"Failed to set context for tid %04x, error %u
\n
"
,
gdbctx
->
other_thread
->
tid
,
GetLastError
()
);
return
packet_error
;
}
...
...
@@ -1601,32 +1536,6 @@ static void packet_query_monitor_mem(struct gdb_context* gdbctx, int len, const
packet_reply
(
gdbctx
,
"OK"
,
2
);
}
static
void
packet_query_monitor_trace
(
struct
gdb_context
*
gdbctx
,
int
len
,
const
char
*
str
)
{
char
buffer
[
128
];
if
(
len
==
0
)
{
snprintf
(
buffer
,
sizeof
(
buffer
),
"trace=%x
\n
"
,
gdbctx
->
trace
);
}
else
if
(
len
>=
2
&&
str
[
0
]
==
'='
)
{
unsigned
val
=
atoi
(
&
str
[
1
]);
snprintf
(
buffer
,
sizeof
(
buffer
),
"trace: %x => %x
\n
"
,
gdbctx
->
trace
,
val
);
gdbctx
->
trace
=
val
;
}
else
{
/* FIXME: ugly but can use error packet here */
packet_reply_cat
(
gdbctx
,
"E00"
);
return
;
}
packet_reply_open
(
gdbctx
);
packet_reply_hex_to_str
(
gdbctx
,
buffer
);
packet_reply_close
(
gdbctx
);
}
struct
query_detail
{
int
with_arg
;
...
...
@@ -1640,7 +1549,6 @@ struct query_detail
{
0
,
"proc"
,
4
,
packet_query_monitor_process
},
{
0
,
"process"
,
7
,
packet_query_monitor_process
},
{
0
,
"mem"
,
3
,
packet_query_monitor_mem
},
{
1
,
"trace"
,
5
,
packet_query_monitor_trace
},
{
0
,
NULL
,
0
,
NULL
},
};
...
...
@@ -1799,9 +1707,7 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
return
packet_reply
(
gdbctx
,
target_xml
,
-
1
);
break
;
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Unknown or malformed query %*.*s
\n
"
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet
);
ERR
(
"Unhandled query %s
\n
"
,
debugstr_an
(
gdbctx
->
in_packet
,
gdbctx
->
in_packet_len
));
return
packet_error
;
}
...
...
@@ -1810,8 +1716,7 @@ static enum packet_return packet_step(struct gdb_context* gdbctx)
/* FIXME: add support for address in packet */
assert
(
gdbctx
->
in_packet_len
==
0
);
if
(
dbg_curr_thread
!=
gdbctx
->
exec_thread
&&
gdbctx
->
exec_thread
)
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_FIXME
)
fprintf
(
stderr
,
"NIY: step on %04x, while last thread is %04x
\n
"
,
FIXME
(
"Can't single-step thread %04x while on thread %04x
\n
"
,
gdbctx
->
exec_thread
->
tid
,
dbg_curr_thread
->
tid
);
gdbctx
->
process
->
be_cpu
->
single_step
(
&
gdbctx
->
context
,
TRUE
);
resume_debuggee
(
gdbctx
,
DBG_CONTINUE
);
...
...
@@ -1902,17 +1807,13 @@ static BOOL extract_packets(struct gdb_context* gdbctx)
while
((
ret
&
packet_last_f
)
==
0
)
{
if
(
gdbctx
->
in_len
&&
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
))
fprintf
(
stderr
,
"In-buf: %*.*s
\n
"
,
gdbctx
->
in_len
,
gdbctx
->
in_len
,
gdbctx
->
in_buf
);
TRACE
(
"Packet: %s
\n
"
,
debugstr_an
(
gdbctx
->
in_buf
,
gdbctx
->
in_len
));
ptr
=
memchr
(
gdbctx
->
in_buf
,
'$'
,
gdbctx
->
in_len
);
if
(
ptr
==
NULL
)
return
FALSE
;
if
(
ptr
!=
gdbctx
->
in_buf
)
{
int
glen
=
ptr
-
gdbctx
->
in_buf
;
/* garbage len */
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Removing garbage: %*.*s
\n
"
,
glen
,
glen
,
gdbctx
->
in_buf
);
WARN
(
"Removing garbage: %s
\n
"
,
debugstr_an
(
gdbctx
->
in_buf
,
glen
));
gdbctx
->
in_len
-=
glen
;
memmove
(
gdbctx
->
in_buf
,
ptr
,
gdbctx
->
in_len
);
}
...
...
@@ -1939,20 +1840,11 @@ static BOOL extract_packets(struct gdb_context* gdbctx)
if
(
packet_entries
[
i
].
key
==
gdbctx
->
in_buf
[
1
])
break
;
}
if
(
i
==
ARRAY_SIZE
(
packet_entries
))
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_COMMAND_ERROR
)
fprintf
(
stderr
,
"Unknown packet request %*.*s
\n
"
,
plen
,
plen
,
&
gdbctx
->
in_buf
[
1
]);
}
WARN
(
"Unhandled packet %s
\n
"
,
debugstr_an
(
&
gdbctx
->
in_buf
[
1
],
plen
));
else
{
gdbctx
->
in_packet
=
gdbctx
->
in_buf
+
2
;
gdbctx
->
in_packet_len
=
plen
-
1
;
if
(
gdbctx
->
trace
&
GDBPXY_TRC_PACKET
)
fprintf
(
stderr
,
"Packet: %c%*.*s
\n
"
,
gdbctx
->
in_buf
[
1
],
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet_len
,
gdbctx
->
in_packet
);
ret
=
(
packet_entries
[
i
].
handler
)(
gdbctx
);
}
switch
(
ret
&
~
packet_last_f
)
...
...
@@ -1961,9 +1853,7 @@ static BOOL extract_packets(struct gdb_context* gdbctx)
case
packet_ok
:
packet_reply
(
gdbctx
,
"OK"
,
2
);
break
;
case
packet_done
:
break
;
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Reply-full: %*.*s
\n
"
,
gdbctx
->
out_len
,
gdbctx
->
out_len
,
gdbctx
->
out_buf
);
TRACE
(
"Reply: %s
\n
"
,
debugstr_an
(
gdbctx
->
out_buf
,
gdbctx
->
out_len
));
i
=
write
(
gdbctx
->
sock
,
gdbctx
->
out_buf
,
gdbctx
->
out_len
);
assert
(
i
==
gdbctx
->
out_len
);
/* if this fails, we'll have to use POLLOUT...
...
...
@@ -1984,15 +1874,13 @@ static BOOL extract_packets(struct gdb_context* gdbctx)
* This would allow us to send the reply with the '+' character (Ack of
* the command) way sooner than we do now.
*/
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Dropping packet, I was too slow to respond
\n
"
);
ERR
(
"Dropping packet; I was too slow to respond
\n
"
);
}
}
else
{
write
(
gdbctx
->
sock
,
"+"
,
1
);
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Dropping packet, invalid checksum %d <> %d
\n
"
,
in_cksum
,
loc_cksum
);
ERR
(
"Dropping packet; invalid checksum %d <> %d
\n
"
,
in_cksum
,
loc_cksum
);
}
gdbctx
->
in_len
-=
plen
+
4
;
memmove
(
gdbctx
->
in_buf
,
end
+
3
,
gdbctx
->
in_len
);
...
...
@@ -2011,18 +1899,12 @@ static int fetch_data(struct gdb_context* gdbctx)
if
(
gdbctx
->
in_len
+
STEP
>
gdbctx
->
in_buf_alloc
)
gdbctx
->
in_buf
=
packet_realloc
(
gdbctx
->
in_buf
,
gdbctx
->
in_buf_alloc
+=
STEP
);
#undef STEP
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"%d %d %*.*s
\n
"
,
gdbctx
->
in_len
,
gdbctx
->
in_buf_alloc
,
gdbctx
->
in_len
,
gdbctx
->
in_len
,
gdbctx
->
in_buf
);
len
=
read
(
gdbctx
->
sock
,
gdbctx
->
in_buf
+
gdbctx
->
in_len
,
gdbctx
->
in_buf_alloc
-
gdbctx
->
in_len
);
if
(
len
<=
0
)
break
;
gdbctx
->
in_len
+=
len
;
assert
(
gdbctx
->
in_len
<=
gdbctx
->
in_buf_alloc
);
if
(
len
<
gdbctx
->
in_buf_alloc
-
gdbctx
->
in_len
)
break
;
}
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"=> %d
\n
"
,
gdbctx
->
in_len
-
in_len
);
return
gdbctx
->
in_len
-
in_len
;
}
...
...
@@ -2045,7 +1927,6 @@ static BOOL gdb_exec(const char* wine_path, unsigned port, unsigned flags)
if
((
f
=
fdopen
(
fd
,
"w+"
))
==
NULL
)
return
FALSE
;
fprintf
(
f
,
"file %s
\n
"
,
wine_path
);
fprintf
(
f
,
"target remote localhost:%d
\n
"
,
ntohs
(
port
));
fprintf
(
f
,
"monitor trace=%d
\n
"
,
GDBPXY_TRC_COMMAND_FIXME
);
fprintf
(
f
,
"set prompt Wine-gdb>
\\
\n
"
);
/* gdb 5.1 seems to require it, won't hurt anyway */
fprintf
(
f
,
"sharedlibrary
\n
"
);
...
...
@@ -2080,8 +1961,7 @@ static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned fl
/* step 1: create socket for gdb connection request */
if
((
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
==
-
1
)
{
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Can't create socket"
);
ERR
(
"Failed to create socket: %s
\n
"
,
strerror
(
errno
));
return
FALSE
;
}
...
...
@@ -2108,7 +1988,7 @@ static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned fl
switch
(
fork
())
{
case
-
1
:
/* error in parent... */
fprintf
(
stderr
,
"Cannot create gdb
\n
"
);
ERR
(
"Failed to start gdb: fork: %s
\n
"
,
strerror
(
errno
)
);
goto
cleanup
;
default:
/* in parent... success */
signal
(
SIGINT
,
SIG_IGN
);
...
...
@@ -2134,8 +2014,7 @@ static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned fl
if
(
gdbctx
->
sock
==
-
1
)
break
;
ret
=
TRUE
;
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Connected on %d
\n
"
,
gdbctx
->
sock
);
TRACE
(
"connected on %d
\n
"
,
gdbctx
->
sock
);
/* don't keep our small packets too long: send them ASAP back to GDB
* without this, GDB really crawls
*/
...
...
@@ -2143,12 +2022,10 @@ static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned fl
}
break
;
case
0
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Poll for cnx failed (timeout)
\n
"
);
ERR
(
"Timed out connecting to gdb
\n
"
);
break
;
case
-
1
:
if
(
gdbctx
->
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Poll for cnx failed (error)
\n
"
);
ERR
(
"Failed to connect to gdb: poll: %s
\n
"
,
strerror
(
errno
));
break
;
default:
assert
(
0
);
...
...
@@ -2176,7 +2053,6 @@ static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigne
gdbctx
->
exec_thread
=
gdbctx
->
other_thread
=
NULL
;
gdbctx
->
last_sig
=
0
;
gdbctx
->
in_trap
=
FALSE
;
gdbctx
->
trace
=
/*GDBPXY_TRC_PACKET | GDBPXY_TRC_COMMAND |*/
GDBPXY_TRC_COMMAND_ERROR
|
GDBPXY_TRC_COMMAND_FIXME
|
GDBPXY_TRC_WIN32_EVENT
;
gdbctx
->
process
=
NULL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
gdbctx
->
wine_segs
);
i
++
)
gdbctx
->
wine_segs
[
i
]
=
0
;
...
...
@@ -2221,8 +2097,7 @@ static int gdb_remote(unsigned flags, unsigned port)
/* got something */
if
(
pollfd
.
revents
&
(
POLLHUP
|
POLLERR
))
{
if
(
gdbctx
.
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Gdb hung up
\n
"
);
ERR
(
"gdb hung up
\n
"
);
/* kill also debuggee process - questionnable - */
detach_debuggee
(
&
gdbctx
,
TRUE
);
doLoop
=
FALSE
;
...
...
@@ -2237,8 +2112,7 @@ static int gdb_remote(unsigned flags, unsigned port)
/* timeout, should never happen (infinite timeout) */
break
;
case
-
1
:
if
(
gdbctx
.
trace
&
GDBPXY_TRC_LOWLEVEL
)
fprintf
(
stderr
,
"Poll failed
\n
"
);
ERR
(
"poll failed: %s
\n
"
,
strerror
(
errno
));
doLoop
=
FALSE
;
break
;
}
...
...
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