Subversion Repositories HelenOS

Rev

Rev 4605 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2008 Jiri Svoboda
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup generic
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #ifndef KERN_UDEBUG_H_
  36. #define KERN_UDEBUG_H_
  37.  
  38. #include <ipc/ipc.h>
  39.  
  40. typedef enum { /* udebug_method_t */
  41.  
  42. /** Start debugging the recipient.
  43.  * Causes all threads in the receiving task to stop. When they
  44.  * are all stoped, an answer with retval 0 is generated.
  45.  */
  46. UDEBUG_M_BEGIN = 1,
  47.  
  48. /** Finish debugging the recipient.
  49.  * Answers all pending GO and GUARD messages.
  50.  */
  51. UDEBUG_M_END,
  52.  
  53. /** Set which events should be captured.
  54.  */
  55. UDEBUG_M_SET_EVMASK,
  56.  
  57. /** Make sure the debugged task is still there.
  58.  * This message is answered when the debugged task dies
  59.  * or the debugging session ends.
  60.  */
  61. UDEBUG_M_GUARD,
  62.  
  63. /** Run a thread until a debugging event occurs.
  64.  * This message is answered when the thread stops
  65.  * in a debugging event.
  66.  *
  67.  * - ARG2 - id of the thread to run
  68.  */
  69. UDEBUG_M_GO,
  70.  
  71. /** Stop a thread being debugged.
  72.  * Creates a special STOP event in the thread, causing
  73.  * it to answer a pending GO message (if any).
  74.  */
  75. UDEBUG_M_STOP,
  76.  
  77. /** Read arguments of a syscall.
  78.  *
  79.  * - ARG2 - thread identification
  80.  * - ARG3 - destination address in the caller's address space
  81.  *
  82.  */
  83. UDEBUG_M_ARGS_READ,
  84.  
  85. /** Read the list of the debugged tasks's threads.
  86.  *
  87.  * - ARG2 - destination address in the caller's address space
  88.  * - ARG3 - size of receiving buffer in bytes
  89.  *
  90.  * The kernel fills the buffer with a series of sysarg_t values
  91.  * (thread ids). On answer, the kernel will set:
  92.  *
  93.  * - ARG2 - number of bytes that were actually copied
  94.  * - ARG3 - number of bytes of the complete data
  95.  *
  96.  */
  97. UDEBUG_M_THREAD_READ,
  98.  
  99. /** Read the debugged tasks's memory.
  100.  *
  101.  * - ARG2 - destination address in the caller's address space
  102.  * - ARG3 - source address in the recipient's address space
  103.  * - ARG4 - size of receiving buffer in bytes
  104.  *
  105.  */
  106. UDEBUG_M_MEM_READ,
  107.  
  108. UDEBUG_M_TASK_MEM_AREAS_READ,
  109.  
  110. UDEBUG_M_THREAD_COPY_KSTACK,
  111.  
  112. UDEBUG_M_THREAD_GET_THREAD_STRUCT,
  113.  
  114. UDEBUG_M_MEM_WRITE,
  115.  
  116. UDEBUG_M_THREAD_RESTORE_THREAD_STRUCT,
  117.  
  118. UDEBUG_M_RESTORE_KSTACK,
  119.  
  120. } udebug_method_t;
  121.  
  122.                
  123. typedef enum {
  124.     UDEBUG_EVENT_FINISHED = 1/**< Debuging session has finished */
  125.     UDEBUG_EVENT_STOP,      /**< Stopped on DEBUG_STOP request */
  126.     UDEBUG_EVENT_SYSCALL_B,     /**< Before beginning syscall execution */
  127.     UDEBUG_EVENT_SYSCALL_E,     /**< After finishing syscall execution */
  128.     UDEBUG_EVENT_THREAD_B,      /**< The task created a new thread */
  129.     UDEBUG_EVENT_THREAD_E       /**< A thread exited */
  130. } udebug_event_t;
  131.  
  132. #define UDEBUG_EVMASK(event) (1 << ((event) - 1))
  133.  
  134. typedef enum {
  135.     UDEBUG_EM_FINISHED  = UDEBUG_EVMASK(UDEBUG_EVENT_FINISHED),
  136.     UDEBUG_EM_STOP      = UDEBUG_EVMASK(UDEBUG_EVENT_STOP),
  137.     UDEBUG_EM_SYSCALL_B = UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_B),
  138.     UDEBUG_EM_SYSCALL_E = UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_E),
  139.     UDEBUG_EM_THREAD_B  = UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_B),
  140.     UDEBUG_EM_THREAD_E  = UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_E),
  141.     UDEBUG_EM_ALL       =
  142.         UDEBUG_EVMASK(UDEBUG_EVENT_FINISHED) |
  143.         UDEBUG_EVMASK(UDEBUG_EVENT_STOP) |
  144.         UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_B) |
  145.         UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_E) |
  146.         UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_B) |
  147.         UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_E)
  148. } udebug_evmask_t;
  149.  
  150. #ifdef KERNEL
  151.  
  152. #include <synch/mutex.h>
  153. #include <arch/interrupt.h>
  154. #include <atomic.h>
  155.  
  156. typedef enum {
  157.     /** Task is not being debugged */
  158.     UDEBUG_TS_INACTIVE,
  159.     /** BEGIN operation in progress (waiting for threads to stop) */
  160.     UDEBUG_TS_BEGINNING,
  161.     /** Debugger fully connected */
  162.     UDEBUG_TS_ACTIVE
  163. } udebug_task_state_t;
  164.  
  165. /** Debugging part of task_t structure.
  166.  */
  167. typedef struct {
  168.     /** Synchronize debug ops on this task / access to this structure */
  169.     mutex_t lock;
  170.     char *lock_owner;
  171.  
  172.     udebug_task_state_t dt_state;
  173.     call_t *begin_call;
  174.     int not_stoppable_count;
  175.     struct task *debugger;
  176.     udebug_evmask_t evmask;
  177. } udebug_task_t;
  178.  
  179. /** Debugging part of thread_t structure.
  180.  */
  181. typedef struct {
  182.     /** Synchronize debug ops on this thread / access to this structure. */
  183.     mutex_t lock;
  184.  
  185.     waitq_t go_wq;
  186.     call_t *go_call;
  187.     unative_t syscall_args[6];
  188.     istate_t *uspace_state;
  189.  
  190.     /** What type of event are we stopped in or 0 if none. */
  191.     udebug_event_t cur_event;
  192.     bool go;        /**< thread is GO */
  193.     bool stoppable;     /**< thread is stoppable */
  194.     bool active;        /**< thread is in a debugging session */
  195. } udebug_thread_t;
  196.  
  197. struct task;
  198. struct thread;
  199.  
  200. void udebug_task_init(udebug_task_t *ut);
  201. void udebug_thread_initialize(udebug_thread_t *ut);
  202.  
  203. void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3,
  204.     unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc,
  205.     bool end_variant);
  206.  
  207. void udebug_thread_b_event_attach(struct thread *t, struct task *ta);
  208. void udebug_thread_e_event(void);
  209.  
  210. void udebug_stoppable_begin(void);
  211. void udebug_stoppable_end(void);
  212.  
  213. void udebug_before_thread_runs(void);
  214.  
  215. int udebug_task_cleanup(struct task *ta);
  216.  
  217. #endif
  218.  
  219. #endif
  220.  
  221. /** @}
  222.  */
  223.