Failed assertion when stepping over instruction in gdbstub #11

Closed
opened 2021-09-03 19:50:36 +02:00 by arrowd · 7 comments
Member

I'm running qemu-e2k -g 1234 helloworld and then attach to it. Issuing stepi GDB command results in

Assertion failed: (!(tcg_ctx->tb_cflags & 0x00000200)), function tcg_gen_goto_tb, file ../tcg/tcg-op.c, line 2738.

Applying the following patch makes the problem go away:

diff --git a/target/e2k/translate.c b/target/e2k/translate.c
index 5486ab35aa..bbb7639043 100644
--- a/target/e2k/translate.c
+++ b/target/e2k/translate.c
@@ -692,21 +692,21 @@ static inline bool use_goto_tb(DisasContext *s, target_ulong pc,
     return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) &&
            (npc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK);
 #else
     return true;
 #endif
 }
 
 static inline void gen_goto_tb(DisasContext *ctx, int tb_num,
     target_ulong pc, target_ulong npc)
 {
-    if (use_goto_tb(ctx, pc, npc))  {
+    if (false)  {
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_tl(cpu_pc, npc);
         tcg_gen_exit_tb(ctx->base.tb, tb_num);
     } else {
         /* jump to another page: currently not optimized */
         tcg_gen_movi_tl(cpu_pc, npc);
         tcg_gen_exit_tb(NULL, 0);
     }
 }
I'm running `qemu-e2k -g 1234 helloworld` and then attach to it. Issuing `stepi` GDB command results in ``` Assertion failed: (!(tcg_ctx->tb_cflags & 0x00000200)), function tcg_gen_goto_tb, file ../tcg/tcg-op.c, line 2738. ``` Applying the following patch makes the problem go away: ``` diff --git a/target/e2k/translate.c b/target/e2k/translate.c index 5486ab35aa..bbb7639043 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -692,21 +692,21 @@ static inline bool use_goto_tb(DisasContext *s, target_ulong pc, return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) && (npc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK); #else return true; #endif } static inline void gen_goto_tb(DisasContext *ctx, int tb_num, target_ulong pc, target_ulong npc) { - if (use_goto_tb(ctx, pc, npc)) { + if (false) { /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, npc); tcg_gen_exit_tb(ctx->base.tb, tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, npc); tcg_gen_exit_tb(NULL, 0); } } ```
Owner

Hi.

396d746b93 should fix the problem but there is another one. Gdb cannot step in/over a syscall because recently in upstream was removed the function to check breakpoints.

<signal handler called>
Cannot access memory at address 0xe20000001800
(gdb) Cannot access memory at address 0xe20000001800

The workaround is to type finish command in gdb.

0x0000004000bbcb58 in write () from /usr/e2k-linux-gnu/lib64/libc.so.6
<signal handler called>
Cannot access memory at address 0xe20000001800
(gdb) Cannot access memory at address 0xe20000001800
(gdb) finish
Run till exit from #0  <signal handler called>
0x0000004000bbcb68 in write () from /usr/e2k-linux-gnu/lib64/libc.so.6
(gdb) si
0x0000004000bbcb70 in write () from /usr/e2k-linux-gnu/lib64/libc.so.6

Hi. https://git.mentality.rip/OpenE2K/qemu-e2k/commit/396d746b93d5e5441a25f2bb767529c277cb7cd4 should fix the problem but there is another one. Gdb cannot step in/over a syscall because recently in upstream was removed the function to check breakpoints. ``` <signal handler called> Cannot access memory at address 0xe20000001800 (gdb) Cannot access memory at address 0xe20000001800 ``` The workaround is to type `finish` command in gdb. ``` 0x0000004000bbcb58 in write () from /usr/e2k-linux-gnu/lib64/libc.so.6 <signal handler called> Cannot access memory at address 0xe20000001800 (gdb) Cannot access memory at address 0xe20000001800 (gdb) finish Run till exit from #0 <signal handler called> 0x0000004000bbcb68 in write () from /usr/e2k-linux-gnu/lib64/libc.so.6 (gdb) si 0x0000004000bbcb70 in write () from /usr/e2k-linux-gnu/lib64/libc.so.6 ```
Author
Member

This indeed does fix the initial problem for me, thanks!

This indeed does fix the initial problem for me, thanks!
Author
Member

Speaking of 396d746b93d5e5441a25f2bb767529c277cb7cd4, what is the point of added e2k_proc_call(env, env->wd.size, env->ip, true); call in case EXCP_DEBUG?

It changes wsz register, according to CPU dump.

Speaking of 396d746b93d5e5441a25f2bb767529c277cb7cd4, what is the point of added ` e2k_proc_call(env, env->wd.size, env->ip, true);` call in `case EXCP_DEBUG`? It changes `wsz` register, according to CPU dump.
Owner

Gdb expects the frame from the interrupted procedure to be on procedure and chain stacks. We also need to manually restore it after returning from gdb.

Gdb expects the frame from the interrupted procedure to be on procedure and chain stacks. We also need to manually restore it after returning from gdb.
Author
Member

We also need to manually restore it after returning from gdb.

Does that mean that after each stepi command I typed in GDB, I need to do some extra steps before continuing running the program?

> We also need to manually restore it after returning from gdb. Does that mean that after each `stepi` command I typed in GDB, I need to do some extra steps before continuing running the program?
Owner

No, you do not have to do that. The frame is restored in e2k_tr_tb_start. You need to set env->is_bp = true and save the current frame when EXCP_DEBUG appears.

        case EXCP_DEBUG:
            // notify restoring code
            env->is_bp = true;
            // save current frame
            // gdb will see current window registers and other things
            e2k_proc_call(env, env->wd.size, env->ip, true);
            gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);

Previously frame saving was done in e2k_tr_breakpoint_check, but this function has been removed in the upstream 1b3e36f3e0.

No, you do not have to do that. The frame is restored in `e2k_tr_tb_start`. You need to set `env->is_bp = true` and save the current frame when `EXCP_DEBUG` appears. ``` case EXCP_DEBUG: // notify restoring code env->is_bp = true; // save current frame // gdb will see current window registers and other things e2k_proc_call(env, env->wd.size, env->ip, true); gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0); ``` Previously frame saving was done in `e2k_tr_breakpoint_check`, but this function has been removed in the upstream https://git.mentality.rip/OpenE2K/qemu-e2k/commit/1b3e36f3e0035f892230ab726e37aeb160db10e9.
Author
Member

Now it is clear, thanks for explanations!

Now it is clear, thanks for explanations!
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: OpenE2K/qemu-e2k#11
No description provided.