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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.