Changeset b2353ed9 in rtems


Ignore:
Timestamp:
Jul 16, 2017, 11:53:11 PM (2 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
8ad4d93
Parents:
2465c01
git-author:
Chris Johns <chrisj@…> (07/16/17 23:53:11)
git-committer:
Chris Johns <chrisj@…> (08/15/17 01:39:22)
Message:

libdebugger: Fixes to debugging, ARM support, locking, and gcc-7.1 warnings.

  • Add printk support to aid multi-core debugging.
  • Add lock trace to aid lock debugging.
  • Fixes to gcc-7.1 warnings.
  • Fixes from ticket #2879.
  • Add verbose command controls.
  • Change using the RTEMS sys/lock.h API to manage exception threads.
  • ARM hardware breakpoint fixes. Support for SMP stepping is not implemented, this requires use of the context id register.

Closes #2879.

Location:
cpukit/libdebugger
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libdebugger/rtems-debugger-arm.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    222223
    223224#if TARGET_DEBUG
     225void rtems_debugger_printk_lock(rtems_interrupt_lock_context* lock_context);
     226void rtems_debugger_printk_unlock(rtems_interrupt_lock_context* lock_context);
     227
    224228static void target_printk(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
    225229static void
    226230target_printk(const char* format, ...)
    227231{
     232  rtems_interrupt_lock_context lock_context;
    228233  va_list ap;
    229234  va_start(ap, format);
     235  rtems_debugger_printk_lock(&lock_context);
    230236  vprintk(format, ap);
     237  rtems_debugger_printk_unlock(&lock_context);
    231238  va_end(ap);
    232239}
     
    262269
    263270/*
     271 * CP register access.
     272 */
     273#define ARM_CP_INSTR(_opc, _cp, _op1, _val, _CRn, _CRm, _op2)           \
     274  #_opc " p" #_cp ", " #_op1 ", %[" #_val "], c" #_CRn ", c" #_CRm ", " #_op2 "\n"
     275
     276#define ARM_CP_WRITE(_cp, _op1, _val, _CRn, _CRm, _op2)    \
     277  do {                                                     \
     278    ARM_SWITCH_REG;                                        \
     279    asm volatile(                                          \
     280      ASM_ARM_MODE                                         \
     281      ARM_CP_INSTR(mcr, _cp, _op1, val, _CRn, _CRm, _op2)  \
     282      ASM_THUMB_MODE                                       \
     283      : ARM_SWITCH_REG_ASM                                 \
     284      : [val] "r" (_val));                                 \
     285  } while (0)
     286
     287#define ARM_CP_READ(_cp, _op1, _val, _CRn, _CRm, _op2)     \
     288  do {                                                     \
     289    ARM_SWITCH_REG;                                        \
     290    asm volatile(                                          \
     291      ASM_ARM_MODE                                         \
     292      ARM_CP_INSTR(mrc, _cp, _op1, val, _CRn, _CRm, _op2)  \
     293      ASM_THUMB_MODE                                       \
     294      : ARM_SWITCH_REG_ASM,                                \
     295        [val] "=&r" (_val));                               \
     296  } while (0)
     297
     298/*
    264299 * Read and write a CP14 register.
    265300 *
     
    269304 * this.
    270305 */
    271 #define ARM_CP14_INSTR(_opc, _val, _CRn, _CRm, _opc2)                   \
    272   #_opc " p14, 0, %[" #_val "], c" #_CRn ", c" #_CRm ", " #_opc2 "\n"
    273 
    274 #define ARM_CP14_WRITE(_val, _CRn, _CRm, _opc2)            \
    275   do {                                                     \
    276     ARM_SWITCH_REG;                                        \
    277     asm volatile(                                          \
    278       ASM_ARM_MODE                                         \
    279       ARM_CP14_INSTR(mcr, val, _CRn, _CRm, _opc2)          \
    280       ASM_THUMB_MODE                                       \
    281       : ARM_SWITCH_REG_ASM                                 \
    282       : [val] "r" (_val));                                 \
    283   } while (0)
    284 
    285 #define ARM_CP14_READ(_val, _CRn, _CRm, _opc2)             \
    286   do {                                                     \
    287     ARM_SWITCH_REG;                                        \
    288     asm volatile(                                          \
    289       ASM_ARM_MODE                                         \
    290       ARM_CP14_INSTR(mrc, val, _CRn, _CRm, _opc2)          \
    291       ASM_THUMB_MODE                                       \
    292       : ARM_SWITCH_REG_ASM,                                \
    293         [val] "=&r" (_val));                               \
    294   } while (0)
     306#define ARM_CP14_WRITE(_val, _CRn, _CRm, _op2) \
     307  ARM_CP_WRITE(14, 0, _val, _CRn, _CRm, _op2)
     308
     309#define ARM_CP14_READ(_val, _CRn, _CRm, _op2)  \
     310  ARM_CP_READ(14, 0, _val, _CRn, _CRm, _op2)
     311
     312/*
     313 * Read and write a CP15 register.
     314 *
     315 * The Context ID register is a process level context and used to scope
     316 * hardware break points.
     317 */
     318#define ARM_CP15_WRITE(_val, _op1, _CRn, _CRm, _op2) \
     319  ARM_CP_WRITE(15, _op1, _val, _CRn, _CRm, _op2)
     320
     321#define ARM_CP15_READ(_val, _op1, _CRn, _CRm, _op2)  \
     322  ARM_CP_READ(15, _op1, _val, _CRn, _CRm, _op2)
    295323
    296324static int
     
    299327  #define ID_VALUE(_i, _h, _l) ((_i >> _l) & ((1 << ((_h - _l) + 1)) -1))
    300328  uint32_t          val;
    301   const char const* vl = "[Invalid version]";
    302   const char const* labels[] = {
     329  const char*      vl = "[Invalid version]";
     330  const char* const labels[] = {
    303331    "ARMv6 [v6]",
    304332    "ARMv6 [v6.1]",
     
    472500arm_debug_break_clear(void)
    473501{
    474   arm_debug_hwbreak* bp = &hw_breaks[0];
    475   int                i;
     502  rtems_interrupt_lock_context lock_context;
     503  arm_debug_hwbreak*           bp = &hw_breaks[0];
     504  int                          i;
     505  rtems_interrupt_lock_acquire(&target_lock, &lock_context);
    476506  for (i = 0; i < hw_breakpoints; ++i, ++bp) {
    477507    bp->enabled = false;
    478508    bp->loaded = false;
    479509  }
    480 }
    481 
     510  rtems_interrupt_lock_release(&target_lock, &lock_context);
     511}
     512
     513static inline void
     514arm_debug_set_context_id(const uint32_t id)
     515{
     516  ARM_CP15_WRITE(id, 0, 13, 0, 1);
     517}
     518
     519/*
     520 * You can only load the hardware breaks points when in the SVC mode or the
     521 * single step inverted break point will trigger.
     522 */
    482523static void
    483524arm_debug_break_load(void)
    484525{
    485   arm_debug_hwbreak* bp = &hw_breaks[0];
    486   int                i;
    487   for (i = 0; i < hw_breakpoints; ++i, ++bp) {
     526  rtems_interrupt_lock_context lock_context;
     527  arm_debug_hwbreak*            bp = &hw_breaks[0];
     528  int                           i;
     529  rtems_interrupt_lock_acquire(&target_lock, &lock_context);
     530  if (bp->enabled && !bp->loaded) {
     531    arm_debug_set_context_id(0xdead1111);
     532    arm_debug_break_write_value(0, bp->value);
     533    arm_debug_break_write_control(0, bp->control);
     534  }
     535  ++bp;
     536  for (i = 1; i < hw_breakpoints; ++i, ++bp) {
    488537    if (bp->enabled && !bp->loaded) {
    489538      bp->loaded = true;
    490       target_printk("]]} hwbp: %i: v:%08lx c:%08lx l:%08x\n",
    491                     i, bp->value, bp->control, bp->length);
    492539      arm_debug_break_write_value(i, bp->value);
    493540      arm_debug_break_write_control(i, bp->control);
    494541    }
    495542  }
     543  rtems_interrupt_lock_release(&target_lock, &lock_context);
    496544}
    497545
     
    499547arm_debug_break_unload(void)
    500548{
    501   arm_debug_hwbreak* bp = &hw_breaks[0];
     549  rtems_interrupt_lock_context lock_context;
     550  arm_debug_hwbreak*           bp = &hw_breaks[0];
    502551  int                i;
     552  rtems_interrupt_lock_acquire(&target_lock, &lock_context);
     553  arm_debug_set_context_id(0);
    503554  for (i = 0; i < hw_breakpoints; ++i, ++bp) {
    504555    bp->loaded = false;
    505556    arm_debug_break_write_control(i, 0);
    506557  }
     558  rtems_interrupt_lock_release(&target_lock, &lock_context);
    507559}
    508560
     
    938990  rtems_interrupt_lock_context lock_context;
    939991  debug_session_active = true;
    940   rtems_interrupt_lock_acquire(&target_lock, &lock_context);
    941992  arm_debug_break_unload();
    942993  arm_debug_break_clear();
     994  rtems_interrupt_lock_acquire(&target_lock, &lock_context);
    943995  rtems_debugger_target_set_vectors();
    944996  rtems_interrupt_lock_release(&target_lock, &lock_context);
     
    9541006  void*                        text_end;
    9551007#endif
     1008  arm_debug_break_unload();
     1009  arm_debug_break_clear();
    9561010  rtems_interrupt_lock_acquire(&target_lock, &lock_context);
    9571011  debug_session_active = false;
     
    10641118
    10651119    /*
    1066      * Only write to debugger controlled threads. Do not touch the registers
    1067      * for threads blocked in the context switcher.
     1120     * Only write to debugger controlled exception threads. Do not touch the
     1121     * registers for threads blocked in the context switcher.
    10681122     */
    10691123    if (rtems_debugger_thread_flag(thread,
    1070                                    RTEMS_DEBUGGER_THREAD_FLAG_DEBUGGING)) {
     1124                                   RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
    10711125      CPU_Exception_frame* frame = thread->frame;
    10721126      frame->register_r0  = regs[REG_R0];
     
    11321186rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread)
    11331187{
    1134   if (rtems_debugger_thread_flag(thread,
    1135                                  (RTEMS_DEBUGGER_THREAD_FLAG_STEP |
    1136                                   RTEMS_DEBUGGER_THREAD_FLAG_STEPPING))) {
     1188  if (rtems_debugger_thread_flag(thread, RTEMS_DEBUGGER_THREAD_FLAG_STEP_INSTR)) {
    11371189    /*
    11381190     * Single stepping and range stepping uses hardware debug breakpoint
     
    11411193    CPU_Exception_frame* frame = thread->frame;
    11421194    arm_debug_hwbreak*   bp = &hw_breaks[0];
    1143     int                  i;
    1144     for (i = 0; i < hw_breakpoints; ++i, ++bp) {
    1145       if (!bp->enabled) {
    1146         const uint32_t addr = (intptr_t) frame->register_pc;
    1147         const bool     thumb = (FRAME_SR & (1 << 5)) != 0 ? true : false;
    1148         uint32_t       bas;
    1149 
    1150         bp->enabled = true;
    1151         bp->loaded = false;
    1152         bp->address = frame->register_pc;
    1153         bp->frame = frame;
    1154         bp->length = sizeof(uint32_t);
    1155 
    1156         if (thumb) {
    1157           uint16_t instr = *((uint16_t*) frame->register_pc);
    1158           switch (instr & 0xf800) {
    1159           case 0xe800:
    1160           case 0xf000:
    1161           case 0xf800:
    1162             break;
    1163           default:
    1164             bp->length = sizeof(uint16_t);
    1165             break;
    1166           }
     1195    target_printk("[} stepping: %s\n", bp->enabled ? "yes" : "no");
     1196    if (!bp->enabled) {
     1197      const uint32_t addr = (intptr_t) frame->register_pc;
     1198      const bool     thumb = (FRAME_SR & (1 << 5)) != 0 ? true : false;
     1199      uint32_t       bas;
     1200
     1201      bp->enabled = true;
     1202      bp->loaded = false;
     1203      bp->address = frame->register_pc;
     1204      bp->frame = frame;
     1205      bp->length = sizeof(uint32_t);
     1206
     1207      if (thumb) {
     1208        uint16_t instr = *((uint16_t*) frame->register_pc);
     1209        switch (instr & 0xf800) {
     1210        case 0xe800:
     1211        case 0xf000:
     1212        case 0xf800:
     1213          break;
     1214        default:
     1215          bp->length = sizeof(uint16_t);
     1216          break;
    11671217        }
    1168 
    1169         /*
    1170          * See table C3-2 Effect of byte address selection on Breakpoint
    1171          * generation and "Instruction address comparisoin programming
    1172          * examples.
    1173          */
    1174         if (thumb) {
    1175           if ((addr & (1 << 1)) == 0) {
    1176             bas = 0x3; /* b0011 */
    1177           }
    1178           else {
    1179             bas = 0xc; /* b1100 */
    1180           }
     1218      }
     1219
     1220      /*
     1221       * See table C3-2 Effect of byte address selection on Breakpoint
     1222       * generation and "Instruction address comparision programming
     1223       * examples.
     1224       */
     1225      if (thumb) {
     1226        if ((addr & (1 << 1)) == 0) {
     1227          bas = 0x3; /* b0011 */
    11811228        }
    11821229        else {
    1183           bas = 0xf; /* b1111 */
     1230          bas = 0xc; /* b1100 */
    11841231        }
    1185 
    1186         arm_debug_break_setup(bp,
    1187                               addr & ~0x3,
    1188                               ARM_HW_BP_UNLINKED_INSTR_MISMATCH,
    1189                               bas,
    1190                               ARM_HW_BP_PRIV_PL0_SUP_SYS);
    1191 
    1192         /*
    1193          * Save the interrupt state before stepping if set.
    1194          */
     1232      }
     1233      else {
     1234        bas = 0xf; /* b1111 */
     1235      }
     1236
     1237      arm_debug_break_setup(bp,
     1238                            addr & ~0x3,
     1239                            ARM_HW_BP_UNLINKED_INSTR_MISMATCH,
     1240                            bas,
     1241                            ARM_HW_BP_PRIV_PL0_SUP_SYS);
     1242
     1243      /*
     1244       * Save the interrupt state before stepping if set.
     1245       */
    11951246#if ARM_PSR_HAS_INT_MASK
    1196         if ((FRAME_SR & CPSR_INTS_MASK) != 0) {
    1197           uint32_t int_state;
    1198           int_state =
    1199             (frame->register_cpsr & CPSR_INTS_MASK) << RTEMS_DEBUGGER_THREAD_FLAG_TARGET_BASE;
    1200           thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_INTS_DISABLED | int_state;
    1201         }
    1202         /*
    1203          * Mask the interrupt when stepping.
    1204          */
    1205         FRAME_SR |= CPSR_INTS_MASK;
    1206 #endif
    1207         break;
     1247      if ((FRAME_SR & CPSR_INTS_MASK) != 0) {
     1248        uint32_t int_state;
     1249        int_state =
     1250          (frame->register_cpsr & CPSR_INTS_MASK) << RTEMS_DEBUGGER_THREAD_FLAG_TARGET_BASE;
     1251        thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_INTS_DISABLED | int_state;
    12081252      }
     1253      /*
     1254       * Mask the interrupt when stepping.
     1255       */
     1256      FRAME_SR |= CPSR_INTS_MASK;
     1257#endif
    12091258    }
    12101259  }
     
    12161265{
    12171266  int sig = RTEMS_DEBUGGER_SIGNAL_HUP;
    1218 #if defined(ARM_EXCEPTION_RESET)
     1267#if defined(ARM_MULTILIB_ARCH_V4)
    12191268  switch (frame->vector) {
    12201269  case ARM_EXCEPTION_RESET:
     
    12411290#endif
    12421291  return sig;
     1292}
     1293
     1294int
     1295rtems_debugger_target_hwbreak_insert(void)
     1296{
     1297  /*
     1298   * Do nothing, load on exit of the exception handler.
     1299   */
     1300  return 0;
     1301}
     1302
     1303int
     1304rtems_debugger_target_hwbreak_remove(void)
     1305{
     1306  arm_debug_break_unload();
     1307  return 0;
    12431308}
    12441309
     
    12631328  rtems_cache_flush_multiple_data_lines(swbreak->address,
    12641329                                        sizeof(breakpoint));
    1265   rtems_cache_invalidate_multiple_instruction_lines(swbreak->address,
    1266                                                     sizeof(breakpoint));
     1330  rtems_cache_instruction_sync_after_code_change(swbreak->address,
     1331                                                 sizeof(breakpoint));
    12671332  return 0;
    12681333}
  • cpukit/libdebugger/rtems-debugger-block.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-block.h

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-cmd.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    181182    }
    182183  }
     184  else if (strcasecmp(argv[1], "verbose") == 0) {
     185    if (!rtems_debugger_running()) {
     186      printf("error: debugger not running.\n");
     187      return 1;
     188    }
     189
     190    if (argc == 3 && strcasecmp(argv[2], "on") == 0) {
     191      rtems_debugger_set_verbose(true);
     192    }
     193    else if (argc == 3 && strcasecmp(argv[2], "off") == 0) {
     194      rtems_debugger_set_verbose(false);
     195    }
     196    else {
     197      printf("debugger verbose: not on or off\n");
     198      return 1;
     199    }
     200  }
    183201  else if (strcasecmp(argv[1], "help") == 0) {
    184202    printf("debugger [start/stop/help] ...\n" \
     
    186204           "  stop\n" \
    187205           "  remote-debug <on/off>\n" \
     206           "  verbose <on/off>\n" \
    188207           "  help\n");
    189208  }
  • cpukit/libdebugger/rtems-debugger-i386.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-remote-tcp.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-remote-tcp.h

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-remote.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-remote.h

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
  • cpukit/libdebugger/rtems-debugger-server.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2425 */
    2526
     27#define RTEMS_DEBUGGER_VERBOSE_LOCK 0
     28#define RTEMS_DEBUGGER_PRINT_PRINTK 1
     29
    2630#include <errno.h>
    2731#include <stdlib.h>
    2832#include <unistd.h>
     33
     34#include <rtems/bspIo.h>
     35#include <rtems/score/smp.h>
    2936
    3037#include <rtems/rtems-debugger.h>
     
    5158typedef struct rtems_debugger_packet
    5259{
    53   const char const*      label;
     60  const char* const      label;
    5461  rtems_debugger_command command;
    5562} rtems_debugger_packet;
     
    5865 * Common error strings.
    5966 */
    60 static const char const* r_OK = "OK";
    61 static const char const* r_E01 = "E01";
     67static const char* const r_OK = "OK";
     68static const char* const r_E01 = "E01";
    6269
    6370/*
     
    7481rtems_debugger_server* rtems_debugger;
    7582
     83/**
     84 * Print lock ot make the prints sequential. This is to debug the debugger in
     85 * SMP.
     86 */
     87#if RTEMS_DEBUGGER_PRINT_PRINTK
     88RTEMS_INTERRUPT_LOCK_DEFINE(static, printk_lock, "printk_lock")
     89#endif
     90
     91void
     92rtems_debugger_printk_lock(rtems_interrupt_lock_context* lock_context)
     93{
     94  rtems_interrupt_lock_acquire(&printk_lock, lock_context);
     95}
     96
     97void
     98rtems_debugger_printk_unlock(rtems_interrupt_lock_context* lock_context)
     99{
     100  rtems_interrupt_lock_release(&printk_lock, lock_context);
     101}
     102
    76103int
    77 rtems_debugger_printf(const char* format, ...)
     104rtems_debugger_clean_printf(const char* format, ...)
    78105{
    79106  int     len;
    80107  va_list ap;
    81108  va_start(ap, format);
    82   len = rtems_vprintf(&rtems_debugger->printer, format, ap);
     109  if (RTEMS_DEBUGGER_PRINT_PRINTK) {
     110    rtems_interrupt_lock_context lock_context;
     111    rtems_debugger_printk_lock(&lock_context);
     112    len = vprintk(format, ap);
     113    rtems_debugger_printk_unlock(&lock_context);
     114  }
     115  else
     116    len = rtems_vprintf(&rtems_debugger->printer, format, ap);
     117  va_end(ap);
     118  return len;
     119}
     120
     121int
     122rtems_debugger_printf(const char* format, ...)
     123{
     124  int     len;
     125  va_list ap;
     126  va_start(ap, format);
     127  if (RTEMS_DEBUGGER_PRINT_PRINTK) {
     128    rtems_interrupt_lock_context lock_context;
     129    rtems_debugger_printk_lock(&lock_context);
     130    printk("[CPU:%d] ", (int) _SMP_Get_current_processor ());
     131    len = vprintk(format, ap);
     132    rtems_debugger_printk_unlock(&lock_context);
     133  }
     134  else
     135    len = rtems_vprintf(&rtems_debugger->printer, format, ap);
    83136  va_end(ap);
    84137  return len;
     
    159212check_pid(DB_UINT pid)
    160213{
    161   return pid == 0|| rtems_debugger->pid == (pid_t) pid;
    162 }
    163 
    164 int
     214  return pid == 0 || rtems_debugger->pid == (pid_t) pid;
     215}
     216
     217void
    165218rtems_debugger_lock(void)
    166219{
    167   if (rtems_debugger->lock != 0) {
    168     rtems_status_code sc;
    169     sc = rtems_semaphore_obtain(rtems_debugger->lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    170     if (sc != RTEMS_SUCCESSFUL) {
    171       rtems_debugger_printf("error: rtems-db: lock: %s\n",
    172                             rtems_status_text(sc));
    173       return -1;
    174     }
    175   }
    176   return 0;
    177 }
    178 
    179 int
     220  _Mutex_recursive_Acquire(&rtems_debugger->lock);
     221}
     222
     223void
    180224rtems_debugger_unlock(void)
    181225{
    182   if (rtems_debugger->lock != 0) {
    183     rtems_status_code sc;
    184     sc = rtems_semaphore_release(rtems_debugger->lock);
    185     if (sc != RTEMS_SUCCESSFUL) {
    186       rtems_debugger_printf("error: rtems-db: unlock: %s\n",
    187                             rtems_status_text(sc));
    188       return -1;
    189     }
    190   }
    191   return 0;
     226  _Mutex_recursive_Release(&rtems_debugger->lock);
    192227}
    193228
     
    195230rtems_debugger_lock_create(void)
    196231{
    197   #define LOCK_ATTRIBUTES \
    198     RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | RTEMS_BINARY_SEMAPHORE
    199   rtems_status_code sc;
    200   sc = rtems_semaphore_create(rtems_build_name('G', 'D', 'B', 's'),
    201                               1,
    202                               LOCK_ATTRIBUTES,
    203                               0,
    204                               &rtems_debugger->lock);
    205   if (sc != RTEMS_SUCCESSFUL) {
    206     rtems_debugger_printf("error: rtems-db: sema create: %s\n",
    207                           rtems_status_text(sc));
    208     errno = EIO;
    209     return -1;
    210   }
     232  _Mutex_recursive_Initialize_named(&rtems_debugger->lock, "DBlock");
    211233  return 0;
    212234}
     
    215237rtems_debugger_lock_destroy(void)
    216238{
    217   rtems_debugger_lock();
    218   if (rtems_debugger->lock != 0) {
    219     rtems_status_code sc;
    220     rtems_semaphore_release(rtems_debugger->lock);
    221     sc = rtems_semaphore_delete(rtems_debugger->lock);
    222     rtems_debugger->lock = 0;
    223     if (sc != RTEMS_SUCCESSFUL) {
    224       rtems_debugger_printf("error: rtems-db: sema delete: %s\n",
    225                             rtems_status_text(sc));
    226       return -1;
    227     }
    228   }
    229239  return 0;
    230240}
     
    334344rtems_debugger_server_events_running(void)
    335345{
    336   bool running;
    337   rtems_debugger_lock();
    338   running = rtems_debugger->events_running;
    339   rtems_debugger_unlock();
    340   return running;
    341 }
    342 
    343 int
    344 rtems_debugger_server_events_wake(void)
    345 {
    346   rtems_status_code sc;
    347   int               r = 0;
    348   sc = rtems_event_send(rtems_debugger->events_task, RTEMS_EVENT_1);
    349   if (sc != RTEMS_SUCCESSFUL) {
    350     rtems_debugger_printf("error: rtems-db: event send: %s\n",
    351                           rtems_status_text(sc));
    352     errno = EIO;
    353     r = -1;
    354   }
    355   return r;
    356 }
    357 
    358 static int
     346  return rtems_debugger->events_running;
     347}
     348
     349void
     350rtems_debugger_server_events_signal(void)
     351{
     352  _Condition_Signal(&rtems_debugger->server_cond);
     353}
     354
     355static void
    359356rtems_debugger_server_events_wait(void)
    360357{
    361   rtems_event_set   out = 0;
    362   rtems_status_code sc;
    363   int               r = 0;
    364   rtems_debugger_unlock();
    365   while (true) {
    366     sc = rtems_event_receive(RTEMS_EVENT_1,
    367                              RTEMS_EVENT_ALL | RTEMS_WAIT,
    368                              RTEMS_NO_TIMEOUT,
    369                              &out);
    370     if (sc != RTEMS_SUCCESSFUL) {
    371       rtems_debugger_printf("error: rtems-db: event receive: %s\n",
    372                             rtems_status_text(sc));
    373       errno = EIO;
    374       r = -1;
    375       break;
    376     }
    377     if (out == RTEMS_EVENT_1)
    378       break;
    379   }
    380   rtems_debugger_lock();
    381   return r;
     358  _Condition_Wait_recursive(&rtems_debugger->server_cond, &rtems_debugger->lock);
    382359}
    383360
     
    433410    rtems_debugger_printf("rtems-db: put:%4zu: ", rtems_debugger->output_level);
    434411    while (i < rtems_debugger->output_level)
    435       rtems_debugger_printf("%c", (char) rtems_debugger->output[i++]);
    436     rtems_debugger_printf("\n");
     412      rtems_debugger_clean_printf("%c", (char) rtems_debugger->output[i++]);
     413    rtems_debugger_clean_printf("\n");
    437414  }
    438415
     
    534511
    535512      if (rtems_debugger->remote_debug)
    536         rtems_debugger_printf("%c", c);
     513        rtems_debugger_clean_printf("%c", c);
    537514
    538515      switch (state) {
     
    541518        case '+':
    542519          if (rtems_debugger->remote_debug) {
    543             rtems_debugger_printf(" [[ACK%s]]\n",
     520            rtems_debugger_clean_printf(" [[ACK%s]]\n",
    544521                                  rtems_debugger->ack_pending ? "" : "?");
    545522            remote_debug_header = true;
     
    549526        case '-':
    550527          if (rtems_debugger->remote_debug) {
    551             rtems_debugger_printf(" [[NACK]]\n");
     528            rtems_debugger_clean_printf(" [[NACK]]\n");
    552529            remote_debug_header = true;
    553530          }
     
    562539          in = 0;
    563540          if (junk && rtems_debugger->remote_debug) {
    564             rtems_debugger_printf("\b [[junk dropped]]\nrtems-db: get:   : $");
     541            rtems_debugger_clean_printf("\b [[junk dropped]]\nrtems-db: get:   : $");
    565542            remote_debug_header = false;
    566543          }
     
    568545        case '\x3':
    569546          if (rtems_debugger->remote_debug)
    570             rtems_debugger_printf("^C [[BREAK]]\n");
     547            rtems_debugger_clean_printf("^C [[BREAK]]\n");
    571548          rtems_debugger->ack_pending = false;
    572549          rtems_debugger->input[0] =  '^';
     
    587564          in = 0;
    588565          if (rtems_debugger->remote_debug) {
    589             rtems_debugger_printf("\n");
     566            rtems_debugger_clean_printf("\n");
    590567            remote_debug_header = true;
    591568          }
     
    614591          state = 'F';
    615592          if (rtems_debugger->remote_debug)
    616             rtems_debugger_printf("\n");
     593            rtems_debugger_clean_printf("\n");
    617594          rtems_debugger_remote_send_ack();
    618595        }
    619596        else {
    620597          if (rtems_debugger->remote_debug) {
    621             rtems_debugger_printf(" [[invalid checksum]]\n");
     598            rtems_debugger_clean_printf(" [[invalid checksum]]\n");
    622599            remote_debug_header = true;
    623600            rtems_debugger_remote_send_nack();
     
    628605      case 'F':
    629606          if (rtems_debugger->remote_debug)
    630             rtems_debugger_printf(" [[extra data: 0x%02x]]", (int) c);
     607            rtems_debugger_clean_printf(" [[extra data: 0x%02x]]", (int) c);
    631608        break;
    632609      default:
     
    811788                (const char*) &buffer[0],
    812789                strlen(p->label)) == 0) {
     790      if (rtems_debugger_server_flag(RTEMS_DEBUGGER_FLAG_VERBOSE_CMDS))
     791        rtems_debugger_printf("rtems-db: cmd: %s [%d] '%s'\n",
     792                              p->label, size, (const char*) buffer);
    813793      r = p->command(buffer, size);
    814794      break;
     
    905885    bool    extended;
    906886    extended = thread_id_decode(comma + 1, &pid, &tid);
    907     if (!extended || (extended && check_pid(pid))) {
     887    if (extended || check_pid(pid)) {
    908888      int r;
    909889      r = rtems_debugger_thread_find_index(tid);
     
    955935  if (p != NULL)
    956936    ++p;
    957   while (p != NULL && p != '\0') {
     937  while (p != NULL && *p != '\0') {
    958938    bool  echo = false;
    959939    char* sc;
     
    10231003remote_gq_attached(uint8_t* buffer, int size)
    10241004{
    1025   const char const* response = "1";
    1026   const char*       colon = strchr((const char*) buffer, ':');
     1005  const char* response = "1";
     1006  const char* colon = strchr((const char*) buffer, ':');
    10271007  if (colon != NULL) {
    10281008    DB_UINT pid = hex_decode_uint((const uint8_t*) colon + 1);
     
    10621042remote_gs_non_stop(uint8_t* buffer, int size)
    10631043{
    1064   const char const* response = r_E01;
     1044  const char* response = r_E01;
    10651045  char*       p = strchr((char*) buffer, ':');
    10661046  if (p != NULL) {
     
    11741154              resume = true;
    11751155            break;
     1156          case 'S':
    11761157          case 's':
    11771158            if (thread != NULL) {
     
    12031184            break;
    12041185          default:
     1186            rtems_debugger_printf("rtems-db: vCont: unkown action: %c\n", action);
    12051187            ok = false;
    12061188            break;
     
    12111193      }
    12121194      else {
     1195        rtems_debugger_printf("rtems-db: vCont: no colon\n");
    12131196        ok = false;
    12141197      }
     
    12581241remote_thread_select(uint8_t* buffer, int size)
    12591242{
    1260   const char const* response = r_OK;
    1261   int*              index = NULL;
     1243  const char* response = r_OK;
     1244  int*        index = NULL;
    12621245
    12631246  if (buffer[1] == 'g')
     
    13001283remote_thread_alive(uint8_t* buffer, int size)
    13011284{
    1302   const char const* response = r_E01;
    1303   DB_UINT           pid = 0;
    1304   DB_UINT           tid = 0;
    1305   bool              extended;
     1285  const char* response = r_E01;
     1286  DB_UINT     pid = 0;
     1287  DB_UINT     tid = 0;
     1288  bool        extended;
    13061289  extended = thread_id_decode((const char*) &buffer[1], &pid, &tid);
    13071290  if (!extended || (extended && check_pid(pid))) {
     
    14241407{
    14251408  rtems_debugger_threads* threads = rtems_debugger->threads;
    1426   const char const*       response = r_E01;
     1409  const char*             response = r_E01;
    14271410  if (threads->selector_gen >= 0
    14281411      && threads->selector_gen < (int) threads->current.level) {
     
    14881471remote_write_memory(uint8_t* buffer, int size)
    14891472{
    1490   const char const* response = r_E01;
    1491   const char*       comma;
    1492   const char*       colon;
     1473  const char* response = r_E01;
     1474  const char* comma;
     1475  const char* colon;
    14931476  comma = strchr((const char*) buffer, ',');
    14941477  colon = strchr((const char*) buffer, ':');
     
    16851668
    16861669  while (rtems_debugger_server_events_running()) {
    1687     r = rtems_debugger_server_events_wait();
    1688     if (r < 0)
    1689       break;
     1670    rtems_debugger_server_events_wait();
    16901671    if (!rtems_debugger_server_events_running())
    16911672      break;
     
    17681749
    17691750  rtems_debugger->events_running = false;
    1770   rtems_debugger_server_events_wake();
     1751  rtems_debugger_server_events_signal();
    17711752
    17721753  rtems_debugger_unlock();
     
    18381819  rtems_debugger->remote_debug = false;
    18391820
     1821  rtems_chain_initialize_empty(&rtems_debugger->exception_threads);
     1822
    18401823  rtems_debugger->remote = rtems_debugger_remote_find(remote);
    18411824  if (rtems_debugger->remote== NULL) {
     
    18521835    free(rtems_debugger);
    18531836    rtems_debugger = NULL;
     1837    return -1;
    18541838  }
    18551839
     
    19081892  int r;
    19091893
    1910 
    19111894  rtems_debugger_lock();
    19121895  rtems_debugger->server_running = true;
     
    19501933  rtems_debugger->server_running = false;
    19511934  rtems_debugger->server_finished = true;
     1935  _Condition_Initialize_named(&rtems_debugger->server_cond, "DBserver");
    19521936  rtems_debugger_unlock();
    19531937
  • cpukit/libdebugger/rtems-debugger-server.h

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    101102#define RTEMS_DEBUGGER_FLAG_VCONT        (1 << 3)
    102103#define RTEMS_DEBUGGER_FLAG_MULTIPROCESS (1 << 4)
     104#define RTEMS_DEBUGGER_FLAG_VERBOSE_LOCK (1 << 5)
     105#define RTEMS_DEBUGGER_FLAG_VERBOSE_CMDS (1 << 6)
    103106
    104107/**
     
    108111typedef struct rtems_debugger_threads rtems_debugger_threads;
    109112typedef struct rtems_debugger_target  rtems_debugger_target;
     113
     114/**
     115 * Local types for the RTEMS-X interface.
     116 */
     117typedef struct _Condition_Control       rtems_rx_cond;
     118typedef struct _Mutex_recursive_Control rtems_rx_mutex;
    110119
    111120/**
     
    117126  int                     timeout;
    118127  rtems_task_priority     priority;
    119   rtems_id                lock;
    120   rtems_id                lock_output;
     128  rtems_rx_mutex          lock;
    121129  rtems_debugger_remote*  remote;
    122130  rtems_id                server_task;
     131  rtems_rx_cond           server_cond;
    123132  volatile bool           server_running;
    124133  volatile bool           server_finished;
     
    135144  uint8_t                 output[RTEMS_DEBUGGER_BUFFER_SIZE];
    136145  rtems_debugger_threads* threads;
     146  rtems_chain_control     exception_threads;
    137147  int                     signal;
    138148  rtems_debugger_target*  target;
     
    148158 */
    149159extern int rtems_debugger_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
     160extern int rtems_debugger_clean_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
     161extern void rtems_debugger_printk_lock(rtems_interrupt_lock_context* lock_context);
     162extern void rtems_debugger_printk_unlock(rtems_interrupt_lock_context* lock_context);
    150163
    151164/**
    152165 * Lock the Debugger.
    153166 */
    154 extern int rtems_debugger_lock(void);
     167extern void rtems_debugger_lock(void);
    155168
    156169/**
    157170 * Unlock the Debugger.
    158171 */
    159 extern int rtems_debugger_unlock(void);
     172extern void rtems_debugger_unlock(void);
    160173
    161174/**
    162175 * Is the server still running?
    163176 */
    164 bool rtems_debugger_server_running(void);
     177extern bool rtems_debugger_server_running(void);
    165178
    166179/**
    167180 * Get the remote handle from the debugger.
    168181 */
    169 rtems_debugger_remote* rtems_debugger_remote_handle(void);
     182extern rtems_debugger_remote* rtems_debugger_remote_handle(void);
    170183
    171184/**
    172185 * Is the debugger connected?
    173186 */
    174 bool rtems_debugger_connected(void);
     187extern bool rtems_debugger_connected(void);
    175188
    176189/**
    177190 * Is the debugger events thread runnins?
    178191 */
    179 bool rtems_debugger_server_events_running(void);
    180 
    181 /**
    182  * Wake events thread in the debug server.
    183  */
    184 extern int rtems_debugger_server_events_wake(void);
     192extern bool rtems_debugger_server_events_running(void);
     193
     194/**
     195 * Signal events thread in the debug server to run.
     196 */
     197extern void rtems_debugger_server_events_signal(void);
    185198
    186199/**
  • cpukit/libdebugger/rtems-debugger-target.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    4142
    4243/**
    43  * Frame signature.
     44 * Exception local stack frame data to synchronise with the debugger
     45 * server's events loop processor.
    4446 */
    45 #define TARGET_FRAME_MAGIC_NUM (2)
    46 #define TARGET_FRAME_MAGIC 0xdeadbeef, 0xb2107016
    47 static const uint32_t
    48   frame_magic[TARGET_FRAME_MAGIC_NUM] = { TARGET_FRAME_MAGIC };
     47typedef struct {
     48  rtems_chain_node     node;
     49  rtems_id             id;
     50  CPU_Exception_frame* frame;
     51  rtems_rx_cond        cond;
     52} rtems_debugger_exception;
    4953
    5054#if TARGET_DEBUG
     
    5458target_printk(const char* format, ...)
    5559{
     60  rtems_interrupt_lock_context lock_context;
    5661  va_list ap;
    5762  va_start(ap, format);
     63  rtems_debugger_printk_lock(&lock_context);
    5864  vprintk(format, ap);
     65  rtems_debugger_printk_unlock(&lock_context);
    5966  va_end(ap);
    6067}
     
    220227        memcpy(loc, &target->breakpoint[0], target->breakpoint_size);
    221228      else {
     229        if (rtems_debugger_verbose())
     230          rtems_debugger_printf("rtems-db:  bp:  in: %p %p %d %d %d\n",
     231                                loc, &target->breakpoint[0],
     232                                (int) target->breakpoint_size,
     233                                (int) i, (int) target->swbreaks.level);
    222234        switch (target->breakpoint_size) {
    223235        case 4:
     
    277289rtems_debugger_target_exception(CPU_Exception_frame* frame)
    278290{
    279   volatile const uint32_t magic[3] = {
    280     (uint32_t) frame, TARGET_FRAME_MAGIC
    281   };
    282 
    283   (void) magic;
    284 
    285291  if (!rtems_interrupt_is_in_progress()) {
    286292    rtems_debugger_threads*              threads = rtems_debugger->threads;
    287     #if USE_THREAD_EXECUTING
    288      Thread_Control*                     thread = _Thread_Executing;
    289     #else
    290      const Per_CPU_Control*              cpu = _Per_CPU_Get_snapshot();
    291      Thread_Control*                     thread = _Per_CPU_Get_executing(cpu);
    292     #endif
     293    Thread_Control*                      thread = _Thread_Get_executing();
     294    const rtems_id                       tid = thread->Object.id;
    293295    rtems_id*                            excludes;
    294     const rtems_id                       tid = thread->Object.id;
    295296    DB_UINT                              pc;
    296297    const rtems_debugger_thread_stepper* stepper;
     298    rtems_debugger_exception             target_exception;
    297299    size_t                               i;
    298300
     
    300302                  " frame:%08" PRIxPTR "\n",
    301303                  tid, (intptr_t) thread, (intptr_t) frame);
     304
     305    rtems_debugger_lock();
    302306
    303307    /*
     
    308312        target_printk("[} server access fault\n");
    309313        rtems_debugger->target->memory_access = true;
     314        rtems_debugger_unlock();
    310315        longjmp(rtems_debugger->target->access_return, -1);
    311316      }
    312317      target_printk("[} server exception\n");
     318      rtems_debugger_unlock();
    313319      return rtems_debugger_target_exc_cascade;
    314320    }
     
    328334         */
    329335        target_printk("[} tid:%08lx: excluded\n", tid);
     336        rtems_debugger_unlock();
    330337        return rtems_debugger_target_exc_cascade;
    331338      }
     
    341348      rtems_debugger_target_thread_stepping(stepper->thread);
    342349      target_printk("[} tid:%08lx: stepping\n", tid);
     350      rtems_debugger_unlock();
    343351      return rtems_debugger_target_exc_step;
    344352    }
     
    347355
    348356    /*
    349      * Tag the thread as being debugged, wake the debug server's event thread,
    350      * then suspend this thread.
    351      */
    352     _Thread_Set_state(thread, STATES_DEBUGGER);
    353     rtems_debugger_server_events_wake();
    354     rtems_task_suspend(tid);
     357     * Initialise the target exception data and queue ready for the debugger
     358     * server's event processor to handle.
     359     */
     360    rtems_chain_initialize_node(&target_exception.node);
     361    target_exception.frame = frame;
     362    target_exception.id = tid;
     363    _Condition_Initialize(&target_exception.cond);
     364
     365    rtems_chain_append_unprotected(&rtems_debugger->exception_threads,
     366                                   &target_exception.node);
     367
     368    /*
     369     * Signal the debug server's thread.
     370     */
     371    rtems_debugger_server_events_signal();
     372
     373    /*
     374     * Block on the exception thread's condition variable unlocking the
     375     * debugger's mutex and letting the server's thread run.
     376     */
     377    _Condition_Wait_recursive(&target_exception.cond, &rtems_debugger->lock);
     378
     379    /*
     380     * Unlock the debugger's lock now the exception is resuming.
     381     */
     382    rtems_debugger_unlock();
    355383
    356384    target_printk("[} tid:%08lx: resuming\n", tid);
     
    364392}
    365393
    366 int
    367 rtems_debugger_target_set_exception_frame(rtems_debugger_thread* thread)
    368 {
    369   int r = 0;
     394void
     395rtems_debugger_target_exception_thread(rtems_debugger_thread* thread)
     396{
     397  rtems_chain_node* node;
    370398  thread->frame = NULL;
    371   thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_DEBUGGING;
    372   if ((thread->tcb->current_state & STATES_DEBUGGER) != 0) {
    373     CPU_Exception_frame* frame = NULL;
    374     DB_UINT*             sp;
    375     int                  i;
    376     sp = (DB_UINT*) rtems_debugger_target_tcb_sp(thread);
    377     for (i = 0; i < 128; ++i) {
    378       if (sp[i] == frame_magic[0] && sp[i + 1] == frame_magic[1]) {
    379         frame = (CPU_Exception_frame*) sp[i + 2];
    380         break;
    381       }
    382     }
    383     _Thread_Clear_state(thread->tcb, STATES_DEBUGGER);
    384     thread->frame = frame;
    385     if (frame != NULL)
    386       thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_DEBUGGING;
    387     else
    388       r = -1;
    389   }
    390   return r;
     399  thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION;
     400  for (node = rtems_chain_first(&rtems_debugger->exception_threads);
     401       !rtems_chain_is_tail(&rtems_debugger->exception_threads, node);
     402       node = rtems_chain_next(node)) {
     403    rtems_debugger_exception* target_exception = (rtems_debugger_exception*) node;
     404    if (target_exception->id == thread->id) {
     405      thread->frame = target_exception->frame;
     406      thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION;
     407    }
     408  }
     409}
     410
     411void
     412rtems_debugger_target_exception_thread_resume(rtems_debugger_thread* thread)
     413{
     414  rtems_chain_node* node;
     415  for (node = rtems_chain_first(&rtems_debugger->exception_threads);
     416       !rtems_chain_is_tail(&rtems_debugger->exception_threads, node);
     417       node = rtems_chain_next(node)) {
     418    rtems_debugger_exception* target_exception = (rtems_debugger_exception*) node;
     419    if (target_exception->id == thread->id) {
     420      rtems_chain_extract(node);
     421      thread->frame = NULL;
     422      thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION;
     423      _Condition_Signal(&target_exception->cond);
     424      break;
     425    }
     426  }
    391427}
    392428
  • cpukit/libdebugger/rtems-debugger-target.h

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    195196
    196197/**
     198 * Insert hardware breakpoints into the hardware.
     199 */
     200extern int rtems_debugger_target_hwbreak_insert(void);
     201
     202/**
     203 * Remove hardware breakpoints from the hardware.
     204 */
     205extern int rtems_debugger_target_hwbreak_remove(void);
     206
     207/**
    197208 * Hardware breakpoints.
    198209 */
     
    209220
    210221/**
    211  * Set the thread's exception stack frame pointer.
    212  */
    213 extern int rtems_debugger_target_set_exception_frame(rtems_debugger_thread* thread);
     222 * See if the thread is an exception thread.
     223 */
     224extern void rtems_debugger_target_exception_thread(rtems_debugger_thread* thread);
     225
     226/**
     227 * If the thread is an exception thread, resume it.
     228 */
     229extern void rtems_debugger_target_exception_thread_resume(rtems_debugger_thread* thread);
    214230
    215231/**
  • cpukit/libdebugger/rtems-debugger-threads.c

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    4445  "DBSs",
    4546  "DBSe",
     47  "IDLE",
    4648};
    4749
     
    241243     * debugged.
    242244     */
    243     r = rtems_debugger_target_set_exception_frame(thread);
    244     if (r < 0) {
    245         rtems_debugger_printf("error: rtems-db: thread: snap: %08lx: not valid frame\n",
    246                               id);
    247     }
     245    rtems_debugger_target_exception_thread(thread);
    248246
    249247    /*
    250      * Read the target registers into the thread register array.
    251      */
    252     rtems_debugger_target_read_regs(thread);
    253 
    254     /*
    255      * Debugger threads are stopped for breakpoint, segv or other errors have
    256      * the RTEMS_DEBUGGER_THREAD_FLAG_DEBUGGING set.
     248     * Exception threads have stopped for breakpoint, segv or other errors.
    257249     */
    258250    if (rtems_debugger_thread_flag(thread,
    259                                    RTEMS_DEBUGGER_THREAD_FLAG_DEBUGGING)) {
     251                                   RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
    260252      rtems_id* stopped;
    261253      r = rtems_debugger_block_resize(&threads->stopped);
     
    277269    }
    278270
     271    /*
     272     * Read the target registers into the thread register array.
     273     */
     274    rtems_debugger_target_read_regs(thread);
     275
    279276    if (rtems_debugger_server_flag(RTEMS_DEBUGGER_FLAG_VERBOSE))
    280277      rtems_debugger_printf("rtems-db: sys: thd: %08lx: signal: %d\n",
     
    301298      rtems_debugger_printf("rtems-db: sys:    : suspending\n");
    302299    r = rtems_debugger_target_swbreak_remove();
     300    if (r == 0)
     301      r = rtems_debugger_target_hwbreak_remove();
    303302    if (r == 0) {
    304303      rtems_debugger_thread* current;
     
    353352    if (rtems_debugger_verbose())
    354353      rtems_debugger_printf("rtems-db: sys:    : resuming\n");
    355     if (!detaching)
     354    if (!detaching) {
    356355      r = rtems_debugger_target_swbreak_insert();
     356      if (r == 0)
     357        r = rtems_debugger_target_hwbreak_insert();
     358    }
    357359    if (r == 0) {
    358360      for (i = 0; i < threads->current.level; ++i) {
     
    361363        int                    rr;
    362364        /*
    363          * Check if resuming, which is continuing, a step, or stepping a range.
     365         * Check if resuming, which can be continuing, a step, or stepping a
     366         * range.
    364367         */
    365368        if (detaching ||
     
    377380            }
    378381          }
    379           sc = rtems_task_resume(thread->id);
    380           if (sc != RTEMS_SUCCESSFUL) {
    381             rtems_debugger_printf("error: rtems-db: thread: resume: %08lx: %s\n",
    382                                   thread->id, rtems_status_text(sc));
     382          if (rtems_debugger_verbose())
     383            rtems_debugger_printf("rtems-db: sys:    : resume: 0x%08lx\n",
     384                                  thread->id);
     385          if (rtems_debugger_thread_flag(thread,
     386                                         RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
     387              rtems_debugger_target_exception_thread_resume(thread);
     388          } else {
     389              sc = rtems_task_resume(thread->id);
     390              if (sc != RTEMS_SUCCESSFUL) {
     391                  rtems_debugger_printf("error: rtems-db: thread: resume: %08lx: %s\n",
     392                                        thread->id, rtems_status_text(sc));
     393              }
    383394          }
    384395          thread->flags &= ~(RTEMS_DEBUGGER_THREAD_FLAG_CONTINUE |
     
    421432    for (i = 0; i < threads->current.level; ++i) {
    422433      rtems_debugger_thread* thread = &current[i];
    423       int                    r;
    424       r = rtems_debugger_thread_continue(thread);
    425       if (r < 0)
    426         break;
     434      if (!rtems_debugger_thread_flag(thread,
     435                                      RTEMS_DEBUGGER_THREAD_FLAG_STEP_INSTR)) {
     436        r = rtems_debugger_thread_continue(thread);
     437        if (r < 0)
     438          break;
     439      }
    427440    }
    428441  }
  • cpukit/libdebugger/rtems-debugger-threads.h

    r2465c01 rb2353ed9  
    11/*
    2  * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
     2 * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
     3 * All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    5253 * Debugger thread flags.
    5354 */
    54 #define RTEMS_DEBUGGER_THREAD_FLAG_DEBUGGING      (1 << 0)
     55#define RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION      (1 << 0)
    5556#define RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID      (1 << 1)
    5657#define RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY      (1 << 2)
     
    163164 */
    164165extern int rtems_debugger_thread_stepping(rtems_debugger_thread* thread,
    165                                           DB_UINT                start,
    166                                           DB_UINT                end);
     166                                          DB_UINT                start,
     167                                          DB_UINT                end);
    167168
    168169/**
     
    197198 */
    198199extern int rtems_debugger_thread_state_str(rtems_debugger_thread* thread,
    199                                            char*                  buffer,
    200                                            size_t                 size);
     200                                           char*                  buffer,
     201                                           size_t                 size);
    201202
    202203/**
     
    215216 */
    216217static inline bool
    217 rtems_debugger_thread_flag(rtems_debugger_thread* thread,
    218                            uint32_t               mask)
     218rtems_debugger_thread_flag(rtems_debugger_thread* thread, uint32_t mask)
    219219{
    220220  return (thread->flags & mask) != 0;
Note: See TracChangeset for help on using the changeset viewer.