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
e8007cc0
Commit
e8007cc0
authored
Feb 10, 2005
by
Oliver Stieber
Committed by
Alexandre Julliard
Feb 10, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added vCont support.
parent
eab1f452
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
214 additions
and
2 deletions
+214
-2
gdbproxy.c
programs/winedbg/gdbproxy.c
+214
-2
No files found.
programs/winedbg/gdbproxy.c
View file @
e8007cc0
...
...
@@ -123,6 +123,15 @@ static inline unsigned char hex_to0(int x)
return
"0123456789abcdef"
[
x
];
}
static
int
hex_to_int
(
const
char
*
src
,
size_t
len
){
unsigned
int
returnval
=
0
;
while
(
len
--
){
returnval
=
hex_from0
(
src
[
0
]);
if
(
len
)
returnval
<<=
4
;
}
return
returnval
;
}
static
void
hex_from
(
void
*
dst
,
const
char
*
src
,
size_t
len
)
{
unsigned
char
*
p
=
dst
;
...
...
@@ -572,7 +581,28 @@ static void resume_debuggee(struct gdb_context* gdbctx, unsigned long cont)
dbg_curr_thread
->
tid
,
cont
);
}
else
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot find last thread (%lu)
\n
"
,
dbg_curr_thread
->
tid
);
fprintf
(
stderr
,
"Cannot find last thread
\n
"
);
}
static
void
resume_debuggee_thread
(
struct
gdb_context
*
gdbctx
,
unsigned
long
cont
,
unsigned
int
threadid
)
{
if
(
dbg_curr_thread
)
{
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
(
!
SetThreadContext
(
dbg_curr_thread
->
handle
,
&
gdbctx
->
context
))
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot set context on thread %lu
\n
"
,
dbg_curr_thread
->
tid
);
if
(
!
ContinueDebugEvent
(
gdbctx
->
process
->
pid
,
dbg_curr_thread
->
tid
,
cont
))
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot continue on %lu (%lu)
\n
"
,
dbg_curr_thread
->
tid
,
cont
);
}
}
else
if
(
gdbctx
->
trace
&
GDBPXY_TRC_WIN32_ERROR
)
fprintf
(
stderr
,
"Cannot find last thread
\n
"
);
}
static
void
wait_for_debuggee
(
struct
gdb_context
*
gdbctx
)
...
...
@@ -866,6 +896,185 @@ static enum packet_return packet_continue(struct gdb_context* gdbctx)
return
packet_reply_status
(
gdbctx
);
}
static
enum
packet_return
packet_verbose
(
struct
gdb_context
*
gdbctx
)
{
int
i
;
int
defaultAction
=
-
1
;
/* magic non action */
unsigned
char
sig
;
int
actions
=
0
;
int
actionIndex
[
20
];
/* allow for upto 20 actions */
int
threadIndex
[
20
];
int
threadCount
=
0
;
unsigned
int
threadIDs
[
100
];
/* TODO: Should make this dynamic */
unsigned
int
threadID
=
0
;
struct
dbg_thread
*
thd
;
/* basic check */
assert
(
gdbctx
->
in_packet_len
>=
4
);
/* OK we have vCont followed by..
* ? for query
* c for packet_continue
* Csig for packet_continue_signal
* s for step
* Ssig for step signal
* and then an optional thread ID at the end..
* *******************************************/
fprintf
(
stderr
,
"trying to process a verbose packet
\n
"
);
/* now check that we've got Cont */
assert
(
strncmp
(
gdbctx
->
in_packet
,
"Cont"
,
4
)
==
0
);
/* Query */
if
(
gdbctx
->
in_packet
[
4
]
==
'?'
){
/*
Reply:
`vCont[;action]...'
The vCont packet is supported. Each action is a supported command in the vCont packet.
`'
The vCont packet is not supported. (this didn't seem to be obayed!)
*/
packet_reply_open
(
gdbctx
);
packet_reply_add
(
gdbctx
,
"vCont"
,
5
);
/* add all the supported actions to the reply (all of them for now)*/
packet_reply_add
(
gdbctx
,
";c"
,
2
);
packet_reply_add
(
gdbctx
,
";C"
,
2
);
packet_reply_add
(
gdbctx
,
";s"
,
2
);
packet_reply_add
(
gdbctx
,
";S"
,
2
);
packet_reply_close
(
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 att */
for
(
i
=
4
;
i
<
gdbctx
->
in_packet_len
-
1
;
i
++
){
if
(
gdbctx
->
in_packet
[
i
]
==
';'
){
threadIndex
[
actions
]
=
0
;
actionIndex
[
actions
++
]
=
i
;
}
else
if
(
gdbctx
->
in_packet
[
i
]
==
':'
){
threadIndex
[
actions
-
1
]
=
i
;
}
}
/* now look up the default action */
for
(
i
=
0
;
i
<
actions
;
i
++
){
if
(
threadIndex
[
i
]
==
0
){
if
(
defaultAction
!=
-
1
){
fprintf
(
stderr
,
"Too many default actions specified
\n
"
);
return
packet_error
;
}
defaultAction
=
i
;
}
}
/* Now, I have this default action thing that needs to be applied to all non counted threads */
/* go through all the threads and stick there id's in the to be done list. */
for
(
thd
=
gdbctx
->
process
->
threads
;
thd
;
thd
=
thd
->
next
)
{
threadIDs
[
threadCount
++
]
=
thd
->
tid
;
/* check to see if we have more threads than I counted on, and tell the user what to do
* (their running winedbg, so I'm sure they can fix the problem from the error message!) */
if
(
threadCount
==
100
){
fprintf
(
stderr
,
"Wow, that's a lot of threads, change threadIDs in wine/programms/winedgb/gdbproxy.c to be higher
\n
"
);
break
;
}
}
/* Ok, now we have... actionIndex full of actions and we know what threads there are, so all
* 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 %lu, while last thread is %lu
\n
"
,
gdbctx
->
exec_thread
->
tid
,
dbg_curr_thread
->
tid
);
/* deal with the threaded stuff first */
for
(
i
=
0
;
i
<
actions
;
i
++
){
if
(
threadIndex
[
i
]
!=
0
){
int
j
,
idLength
=
0
;
if
(
i
<
actions
-
1
){
idLength
=
(
actionIndex
[
i
+
1
]
-
threadIndex
[
i
])
-
1
;
}
else
{
idLength
=
(
gdbctx
->
in_packet_len
-
threadIndex
[
i
])
-
1
;
}
threadID
=
hex_to_int
(
gdbctx
->
in_packet
+
threadIndex
[
i
]
+
1
,
idLength
);
/* process the action */
switch
(
gdbctx
->
in_packet
[
actionIndex
[
i
]
+
1
]){
case
's'
:
/* step */
be_cpu
->
single_step
(
&
gdbctx
->
context
,
TRUE
);
/* fall through*/
case
'c'
:
/* continue */
resume_debuggee_thread
(
gdbctx
,
DBG_CONTINUE
,
threadID
);
break
;
case
'S'
:
/* step Sig, */
be_cpu
->
single_step
(
&
gdbctx
->
context
,
TRUE
);
/* fall through */
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
);
if
(
sig
!=
gdbctx
->
last_sig
)
return
packet_error
;
resume_debuggee_thread
(
gdbctx
,
DBG_EXCEPTION_NOT_HANDLED
,
threadID
);
break
;
}
for
(
j
=
0
;
j
<
threadCount
;
j
++
){
if
(
threadIDs
[
j
]
==
threadID
){
threadIDs
[
j
]
=
0
;
break
;
}
}
}
}
/* for i=0 ; i< actions */
/* now we have manage the default action */
if
(
defaultAction
>=
0
){
for
(
i
=
0
;
i
<
threadCount
;
i
++
){
/* check to see if we've already done something to the thread*/
if
(
threadIDs
[
i
]
!=
0
){
/* if not apply the default action*/
threadID
=
threadIDs
[
i
];
/* process the action (yes this is almost identical to the one above!) */
switch
(
gdbctx
->
in_packet
[
actionIndex
[
defaultAction
]
+
1
]){
case
's'
:
/* step */
be_cpu
->
single_step
(
&
gdbctx
->
context
,
TRUE
);
/* fall through */
case
'c'
:
/* continue */
resume_debuggee_thread
(
gdbctx
,
DBG_CONTINUE
,
threadID
);
break
;
case
'S'
:
be_cpu
->
single_step
(
&
gdbctx
->
context
,
TRUE
);
/* fall through */
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
);
if
(
sig
!=
gdbctx
->
last_sig
)
return
packet_error
;
resume_debuggee_thread
(
gdbctx
,
DBG_EXCEPTION_NOT_HANDLED
,
threadID
);
break
;
}
}
}
}
/* if(defaultAction >=0) */
wait_for_debuggee
(
gdbctx
);
be_cpu
->
single_step
(
&
gdbctx
->
context
,
FALSE
);
return
packet_reply_status
(
gdbctx
);
}
static
enum
packet_return
packet_continue_signal
(
struct
gdb_context
*
gdbctx
)
{
unsigned
char
sig
;
...
...
@@ -1604,7 +1813,7 @@ struct packet_entry
static
struct
packet_entry
packet_entries
[]
=
{
/*
{'!', packet_extended}, */
/*
{'!', packet_extended}, */
{
'?'
,
packet_last_signal
},
{
'c'
,
packet_continue
},
{
'C'
,
packet_continue_signal
},
...
...
@@ -1618,9 +1827,12 @@ static struct packet_entry packet_entries[] =
/* {'p', packet_read_register}, doesn't seem needed */
{
'P'
,
packet_write_register
},
{
'q'
,
packet_query
},
/* {'Q', packet_set}, */
/* {'R', packet,restart}, only in extended mode ! */
{
's'
,
packet_step
},
/*{'S', packet_step_signal}, hard(er) to implement */
{
'T'
,
packet_thread_alive
},
{
'v'
,
packet_verbose
},
{
'z'
,
packet_remove_breakpoint
},
{
'Z'
,
packet_set_breakpoint
},
};
...
...
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