Skip to content

Commit 9b46790

Browse files
committed
monitor: fix bug 2177
If we are leaving the monitor with a change in program flow, and there is a breakpoint on the new address, take the breakpoint right away instead of leaving the monitor. The monitor command "G XXXX" is considered a change in flow. This is because of the structure of the DO_INTERRUPT() macro, which can enter the monitor under different conditions in different places, but each only once per executed instruction. git-svn-id: https://svn.code.sf.net/p/vice-emu/code/trunk@45822 379a1393-f5fb-40a0-bcee-ef074d9b53f7
1 parent ae870a8 commit 9b46790

File tree

5 files changed

+58
-33
lines changed

5 files changed

+58
-33
lines changed

vice/src/monitor/mon_breakpoint.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ int breakpoint_add_checkpoint(MON_ADDR start_addr, MON_ADDR end_addr,
689689
update_checkpoint_state(mem);
690690

691691
if (is_temp) {
692-
exit_mon = 1;
692+
exit_mon = exit_mon_continue;
693693
}
694694

695695
if (do_print) {

vice/src/monitor/mon_file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ int mon_autostart(const char *image_name,
506506

507507
/* leave monitor but return after autostart */
508508
autostart_trigger_monitor(1);
509-
exit_mon = 1;
509+
exit_mon = exit_mon_continue;
510510

511511
return result;
512512
}

vice/src/monitor/monitor.c

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ typedef struct symbol_table symbol_table_t;
163163
extern void set_yydebug(int debug);
164164

165165
static char *last_cmd = NULL;
166-
int exit_mon = 0;
166+
enum exit_mon exit_mon = exit_mon_no;
167167
/* flag used by the single-stepping commands to prevent switching forth and back
168168
* to the emulator window when stepping a single instruction. note that this is
169169
* different from what keep_monitor_open does :)
@@ -986,18 +986,18 @@ void mon_set_mem_val_ex(MEMSPACE mem, int bank, uint16_t mem_addr, uint8_t val)
986986
}
987987
}
988988

989-
/* exit monitor */
989+
/* exit monitor, G XXXX */
990990
void mon_jump(MON_ADDR addr)
991991
{
992992
mon_evaluate_default_addr(&addr);
993993
(monitor_cpu_for_memspace[addr_memspace(addr)]->mon_register_set_val)(addr_memspace(addr), e_PC, (uint16_t)(addr_location(addr)));
994-
exit_mon = 1;
994+
exit_mon = exit_mon_change_flow;
995995
}
996996

997-
/* exit monitor */
997+
/* exit monitor, G (not G XXXX) */
998998
void mon_go(void)
999999
{
1000-
exit_mon = 1;
1000+
exit_mon = exit_mon_continue;
10011001
mon_console_suspend_on_leaving = 0;
10021002

10031003
if (should_pause_on_exit_mon || ui_pause_active()) {
@@ -1009,7 +1009,7 @@ void mon_go(void)
10091009
/* exit monitor, close monitor window */
10101010
void mon_exit(void)
10111011
{
1012-
exit_mon = 1;
1012+
exit_mon = exit_mon_continue;
10131013
mon_console_close_on_leaving = 1;
10141014

10151015
if (should_pause_on_exit_mon || ui_pause_active()) {
@@ -1026,7 +1026,7 @@ void mon_exit(void)
10261026
*/
10271027
void mon_quit(void)
10281028
{
1029-
exit_mon = 2;
1029+
exit_mon = exit_mon_quit_vice;
10301030
}
10311031

10321032
void mon_keyboard_feed(const char *string)
@@ -1337,7 +1337,7 @@ void mon_reset_machine(int type)
13371337
switch (type) {
13381338
case 1:
13391339
machine_trigger_reset(MACHINE_RESET_MODE_POWER_CYCLE);
1340-
exit_mon = 1;
1340+
exit_mon = exit_mon_continue;
13411341
break;
13421342
case 8:
13431343
case 9:
@@ -1347,7 +1347,7 @@ void mon_reset_machine(int type)
13471347
break;
13481348
default:
13491349
machine_trigger_reset(MACHINE_RESET_MODE_RESET_CPU);
1350-
exit_mon = 1;
1350+
exit_mon = exit_mon_continue;
13511351
break;
13521352
}
13531353
}
@@ -1642,7 +1642,7 @@ void monitor_init(monitor_interface_t *maincpu_interface_init,
16421642
} else if (init_break_mode == ON_RESET) {
16431643
mon_breakpoint_add_checkpoint((uint16_t)0, (uint16_t)0xffff,
16441644
true, e_exec, true, false);
1645-
exit_mon = 0;
1645+
exit_mon = exit_mon_no;
16461646
#endif
16471647
}
16481648
}
@@ -2566,7 +2566,7 @@ void mon_instructions_step(int count)
25662566
instruction_count = (count >= 0) ? count : 1;
25672567
wait_for_return_level = 0;
25682568
skip_jsrs = false;
2569-
exit_mon = 1;
2569+
exit_mon = exit_mon_continue;
25702570

25712571
mon_console_suspend_on_leaving = 0;
25722572

@@ -2585,7 +2585,7 @@ void mon_instructions_next(int count)
25852585
}
25862586
wait_for_return_level = (int)((MONITOR_GET_OPCODE(default_memspace) == OP_JSR) ? 1 : 0);
25872587
skip_jsrs = true;
2588-
exit_mon = 1;
2588+
exit_mon = exit_mon_continue;
25892589

25902590
mon_console_suspend_on_leaving = 0;
25912591

@@ -2602,7 +2602,7 @@ void mon_instruction_return(void)
26022602
|| MONITOR_GET_OPCODE(default_memspace) == OP_RTI) ?
26032603
0 : (MONITOR_GET_OPCODE(default_memspace) == OP_JSR) ? 2 : 1);
26042604
skip_jsrs = true;
2605-
exit_mon = 1;
2605+
exit_mon = exit_mon_continue;
26062606

26072607
monitor_mask[default_memspace] |= MI_STEP;
26082608
interrupt_monitor_trap_on(mon_interfaces[default_memspace]->int_status);
@@ -3073,7 +3073,7 @@ static void monitor_open(void)
30733073

30743074
if (console_log == NULL) {
30753075
log_error(LOG_DEFAULT, "monitor_open: could not open monitor console.");
3076-
exit_mon = 1;
3076+
exit_mon = exit_mon_continue;
30773077
return;
30783078
}
30793079

@@ -3199,7 +3199,7 @@ static void monitor_open(void)
31993199
#endif
32003200
}
32013201

3202-
static int monitor_process(char *cmd)
3202+
static void monitor_process(char *cmd)
32033203
{
32043204
char *trimmed_command;
32053205

@@ -3240,16 +3240,14 @@ static int monitor_process(char *cmd)
32403240
lib_free(last_cmd);
32413241

32423242
/* remember last command, except when leaving the monitor */
3243-
if (exit_mon && mon_console_suspend_on_leaving) {
3243+
if (exit_mon != exit_mon_no && mon_console_suspend_on_leaving) {
32443244
lib_free(cmd);
32453245
last_cmd = NULL;
32463246
} else {
32473247
last_cmd = cmd;
32483248
}
32493249

32503250
uimon_notify_change();
3251-
3252-
return exit_mon;
32533251
}
32543252

32553253
static void monitor_close(bool check_exit)
@@ -3259,18 +3257,14 @@ static void monitor_close(bool check_exit)
32593257
#endif
32603258
inside_monitor = false;
32613259

3262-
if (exit_mon) {
3263-
exit_mon--;
3264-
}
3265-
3266-
if (check_exit && exit_mon) {
3260+
if (check_exit && exit_mon == exit_mon_quit_vice) {
32673261
if (!monitor_is_remote()) {
32683262
uimon_window_close();
32693263
}
32703264
archdep_vice_exit(0);
32713265
}
32723266

3273-
exit_mon = 0;
3267+
exit_mon = exit_mon_no;
32743268

32753269
if (!monitor_is_remote() && !monitor_is_binary()) {
32763270
if (mon_console_suspend_on_leaving) {
@@ -3299,6 +3293,19 @@ static void monitor_close(bool check_exit)
32993293
vsync_suspend_speed_eval();
33003294
}
33013295

3296+
static int check_for_breakpoint(MEMSPACE mem)
3297+
{
3298+
int reg_pc;
3299+
3300+
if (mem == e_default_space) {
3301+
mem = default_memspace;
3302+
}
3303+
3304+
reg_pc = (monitor_cpu_for_memspace[mem]->mon_register_get_val)(mem, e_PC);
3305+
3306+
return monitor_check_breakpoints(mem, (uint16_t)reg_pc);
3307+
}
3308+
33023309
void monitor_startup(MEMSPACE mem)
33033310
{
33043311
char prompt[40];
@@ -3326,7 +3333,7 @@ void monitor_startup(MEMSPACE mem)
33263333
}
33273334

33283335
monitor_open();
3329-
while (!exit_mon) {
3336+
for (;;) {
33303337

33313338
if (playback_fp) {
33323339
playback_next_command();
@@ -3343,13 +3350,23 @@ void monitor_startup(MEMSPACE mem)
33433350
make_prompt(prompt);
33443351
p = uimon_in(prompt);
33453352
if (p) {
3346-
exit_mon = monitor_process(p);
3347-
} else if (exit_mon < 1) {
3353+
monitor_process(p);
3354+
} else if (exit_mon == exit_mon_no) {
33483355
mon_exit();
33493356
}
33503357
}
33513358

3352-
if (exit_mon) {
3359+
if (exit_mon == exit_mon_change_flow) {
3360+
/*
3361+
* If we are about to exit the monitor with a change of program flow,
3362+
* check if we land on a breakpoint and if so, do not exit.
3363+
*/
3364+
if (check_for_breakpoint(mem)) {
3365+
exit_mon = exit_mon_no;
3366+
}
3367+
}
3368+
3369+
if (exit_mon != exit_mon_no) {
33533370
/* mon_out("exit\n"); */
33543371
break;
33553372
}

vice/src/monitor/monitor_binary.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ static void monitor_binary_process_resource_set(binary_command_t *command)
10281028

10291029
static void monitor_binary_process_exit(binary_command_t *command)
10301030
{
1031-
exit_mon = 1;
1031+
exit_mon = exit_mon_continue;
10321032

10331033
monitor_binary_response(0, e_MON_RESPONSE_EXIT, e_MON_ERR_OK, command->request_id, NULL);
10341034
}
@@ -1955,7 +1955,7 @@ int monitor_binary_get_command_line(void)
19551955

19561956
monitor_binary_process_command(buffer);
19571957

1958-
if (exit_mon) {
1958+
if (exit_mon != exit_mon_no) {
19591959
return 0;
19601960
}
19611961
}

vice/src/monitor/montypes.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,15 @@ struct monitor_cpu_type_s;
237237
extern struct console_s *console_log;
238238
extern int sidefx;
239239
extern int break_on_dummy_access;
240-
extern int exit_mon;
240+
241+
enum exit_mon {
242+
exit_mon_no = 0, /* Do not exit the monitor */
243+
exit_mon_continue = 1, /* Exit and continue normal program flow */
244+
exit_mon_change_flow = 2, /* Exit with changed program flow */
245+
exit_mon_quit_vice = 3 /* Exit monitor and even the whole VICE */
246+
};
247+
248+
extern enum exit_mon exit_mon;
241249

242250
extern RADIXTYPE default_radix;
243251
extern MEMSPACE default_memspace;

0 commit comments

Comments
 (0)