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