Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-debugger.c view on Meta::CPAN
* Get the thread identifier associated with the current thread.
* The return values are normally values like 1, 2, 3, etc, allowing
* the user interface to report messages like "thread 3 has stopped
* at a breakpoint".
* @end deftypefun
@*/
jit_debugger_thread_id_t jit_debugger_get_self(jit_debugger_t dbg)
{
jit_thread_id_t id = jit_thread_self();
jit_debugger_thread_id_t thread;
thread = jit_debugger_get_thread(dbg, &id);
jit_thread_release_self(id);
return thread;
}
/*@
* @deftypefun jit_debugger_thread_id_t jit_debugger_get_thread (jit_debugger_t @var{dbg}, const void *@var{native_thread})
* Get the thread identifier for a specific native thread. The
* @var{native_thread} pointer is assumed to point at a block
* of memory containing a native thread handle. This would be a
* @code{pthread_t} on Pthreads platforms or a @code{HANDLE}
* on Win32 platforms. If the native thread has not been seen
* previously, then a new thread identifier is allocated.
* @end deftypefun
@*/
jit_debugger_thread_id_t jit_debugger_get_thread
(jit_debugger_t dbg, const void *native_thread)
{
/* TODO */
return 0;
}
/*@
* @deftypefun int jit_debugger_get_native_thread (jit_debugger_t @var{dbg}, jit_debugger_thread_id_t @var{thread}, void *@var{native_thread})
* Get the native thread handle associated with a debugger thread identifier.
* Returns non-zero if OK, or zero if the debugger thread identifier is not
* yet associated with a native thread handle.
* @end deftypefun
@*/
int jit_debugger_get_native_thread
(jit_debugger_t dbg, jit_debugger_thread_id_t thread,
void *native_thread)
{
jit_debugger_thread_t th;
lock_debugger(dbg);
th = get_specific_thread(dbg, thread);
if(th)
{
jit_memcpy(native_thread, &(th->native_id), sizeof(th->native_id));
unlock_debugger(dbg);
return 1;
}
else
{
unlock_debugger(dbg);
return 0;
}
}
/*@
* @deftypefun void jit_debugger_set_breakable (jit_debugger_t @var{dbg}, const void *@var{native_thread}, int @var{flag})
* Set a flag that indicates if a native thread can stop at breakpoints.
* If set to 1 (the default), breakpoints will be active on the thread.
* If set to 0, breakpoints will be ignored on the thread. Typically
* this is used to mark threads associated with the debugger's user
* interface, or the virtual machine's finalization thread, so that they
* aren't accidentally suspended by the debugger (which might cause a
* deadlock).
* @end deftypefun
@*/
void jit_debugger_set_breakable
(jit_debugger_t dbg, const void *native_thread, int flag)
{
jit_debugger_thread_t th;
jit_debugger_thread_id_t id;
id = jit_debugger_get_thread(dbg, native_thread);
lock_debugger(dbg);
th = get_specific_thread(dbg, id);
if(th)
{
th->breakable = flag;
}
unlock_debugger(dbg);
}
/*@
* @deftypefun void jit_debugger_attach_self (jit_debugger_t @var{dbg}, int @var{stop_immediately})
* Attach the current thread to a debugger. If @var{stop_immediately}
* is non-zero, then the current thread immediately suspends, waiting for
* the user to start it with @code{jit_debugger_run}. This function is
* typically called in a thread's startup code just before any "real work"
* is performed.
* @end deftypefun
@*/
void jit_debugger_attach_self(jit_debugger_t dbg, int stop_immediately)
{
jit_debugger_event_t *event;
jit_debugger_thread_t th;
lock_debugger(dbg);
th = get_current_thread(dbg);
if(th)
{
event = alloc_event();
if(event)
{
event->type = JIT_DEBUGGER_TYPE_ATTACH_THREAD;
event->thread = th->id;
event->data1 = (jit_nint)stop_immediately;
add_event(dbg, event);
th->find_func = 0;
th->last_data1 = 0;
th->last_func_data1 = 0;
if(stop_immediately)
{
th->run_type = JIT_RUN_TYPE_STOPPED;
suspend_thread(dbg, th);
}
else
{
th->run_type = JIT_RUN_TYPE_CONTINUE;
}
}
}
unlock_debugger(dbg);
}
/*@
* @deftypefun void jit_debugger_detach_self (jit_debugger_t @var{dbg})
* Detach the current thread from the debugger. This is typically
* called just before the thread exits.
* @end deftypefun
@*/
void jit_debugger_detach_self(jit_debugger_t dbg)
{
jit_debugger_event_t *event;
jit_debugger_thread_t th;
lock_debugger(dbg);
th = get_current_thread(dbg);
if(th)
{
event = alloc_event();
if(event)
{
event->type = JIT_DEBUGGER_TYPE_DETACH_THREAD;
event->thread = th->id;
add_event(dbg, event);
th->run_type = JIT_RUN_TYPE_DETACHED;
}
}
unlock_debugger(dbg);
}
/*@
* @deftypefun int jit_debugger_wait_event (jit_debugger_t @var{dbg}, jit_debugger_event_t *@var{event}, jit_nint @var{timeout})
* Wait for the next debugger event to arrive. Debugger events typically
* indicate breakpoints that have occurred. The @var{timeout} is in
* milliseconds, or -1 for an infinite timeout period. Returns non-zero
* if an event has arrived, or zero on timeout.
* @end deftypefun
@*/
int jit_debugger_wait_event
(jit_debugger_t dbg, jit_debugger_event_t *event, jit_int timeout)
{
jit_debugger_linked_event_t *levent;
jit_monitor_lock(&(dbg->queue_lock));
if((levent = dbg->events) == 0)
{
if(!jit_monitor_wait(&(dbg->queue_lock), timeout))
{
jit_monitor_unlock(&(dbg->queue_lock));
return 0;
}
levent = dbg->events;
}
*event = levent->event;
dbg->events = levent->next;
if(!(levent->next))
{
dbg->last_event = 0;
}
jit_free(levent);
jit_monitor_unlock(&(dbg->queue_lock));
return 1;
}
/*@
* @deftypefun jit_debugger_breakpoint_id_t jit_debugger_add_breakpoint (jit_debugger_t @var{dbg}, jit_debugger_breakpoint_info_t @var{info})
* Add a hard breakpoint to a debugger instance. The @var{info} structure
* defines the conditions under which the breakpoint should fire.
* The fields of @var{info} are as follows:
*
* @table @code
* @item flags
* Flags that indicate which of the following fields should be matched.
* If a flag is not present, then all possible values of the field will match.
* Valid flags are @code{JIT_DEBUGGER_FLAG_THREAD},
* @code{JIT_DEBUGGER_FLAG_FUNCTION}, @code{JIT_DEBUGGER_FLAG_DATA1},
* and @code{JIT_DEBUGGER_FLAG_DATA2}.
*
* @item thread
* The thread to match against, if @code{JIT_DEBUGGER_FLAG_THREAD} is set.
*
* @item function
* The function to match against, if @code{JIT_DEBUGGER_FLAG_FUNCTION} is set.
*
* @item data1
* The @code{data1} value to match against, if @code{JIT_DEBUGGER_FLAG_DATA1}
* is set.
*
* @item data2
* The @code{data2} value to match against, if @code{JIT_DEBUGGER_FLAG_DATA2}
* is set.
* @end table
*
* The following special values for @code{data1} are recommended for marking
* breakpoint locations with @code{jit_insn_mark_breakpoint}:
*
* @table @code
* @item JIT_DEBUGGER_DATA1_LINE
* Breakpoint location that corresponds to a source line. This is used
* to determine where to continue to upon a "step".
*
* @item JIT_DEBUGGER_DATA1_ENTER
* Breakpoint location that corresponds to the start of a function.
*
* @item JIT_DEBUGGER_DATA1_LEAVE
* Breakpoint location that corresponds to the end of a function, just
* prior to a @code{return} statement. This is used to determine where
* to continue to upon a "finish".
*
* @item JIT_DEBUGGER_DATA1_THROW
* Breakpoint location that corresponds to an exception throw.
* @end table
* @end deftypefun
@*/
jit_debugger_breakpoint_id_t jit_debugger_add_breakpoint
(jit_debugger_t dbg, jit_debugger_breakpoint_info_t info)
{
/* TODO */
return 0;
}
/*@
* @deftypefun void jit_debugger_remove_breakpoint (jit_debugger_t @var{dbg}, jit_debugger_breakpoint_id_t @var{id})
* Remove a previously defined breakpoint from a debugger instance.
* @end deftypefun
@*/
void jit_debugger_remove_breakpoint
(jit_debugger_t dbg, jit_debugger_breakpoint_id_t id)
{
/* TODO */
}
/*@
* @deftypefun void jit_debugger_remove_all_breakpoints (jit_debugger_t @var{dbg})
* Remove all breakpoints from a debugger instance.
* @end deftypefun
@*/
void jit_debugger_remove_all_breakpoints(jit_debugger_t dbg)
{
/* TODO */
}
/*@
* @deftypefun int jit_debugger_is_alive (jit_debugger_t @var{dbg}, jit_debugger_thread_id_t @var{thread})
* Determine if a particular thread is still alive.
* @end deftypefun
@*/
int jit_debugger_is_alive(jit_debugger_t dbg, jit_debugger_thread_id_t thread)
{
/* TODO */
return 1;
}
/*@
* @deftypefun int jit_debugger_is_running (jit_debugger_t @var{dbg}, jit_debugger_thread_id_t @var{thread})
* Determine if a particular thread is currently running (non-zero) or
* stopped (zero).
* @end deftypefun
@*/
int jit_debugger_is_running(jit_debugger_t dbg, jit_debugger_thread_id_t thread)
{
jit_debugger_thread_t th;
int flag = 0;
lock_debugger(dbg);
th = get_specific_thread(dbg, thread);
if(th)
{
flag = (th->run_type != JIT_RUN_TYPE_STOPPED);
}
unlock_debugger(dbg);
return flag;
}
/*@
* @deftypefun void jit_debugger_run (jit_debugger_t @var{dbg}, jit_debugger_thread_id_t @var{thread})
* Start the specified thread running, or continue from the last breakpoint.
*
* This function, and the others that follow, sends a request to the specified
* thread and then returns to the caller immediately.
* @end deftypefun
@*/
void jit_debugger_run(jit_debugger_t dbg, jit_debugger_thread_id_t thread)
{
jit_debugger_thread_t th;
lock_debugger(dbg);
th = get_specific_thread(dbg, thread);
if(th && th->run_type == JIT_RUN_TYPE_STOPPED)
{
th->run_type = JIT_RUN_TYPE_CONTINUE;
wakeup_all(dbg);
}
unlock_debugger(dbg);
}
/*@
* @deftypefun void jit_debugger_step (jit_debugger_t @var{dbg}, jit_debugger_thread_id_t @var{thread})
* Step over a single line of code. If the line performs a method call,
* then this will step into the call. The request will be ignored if
* the thread is currently running.
* @end deftypefun
@*/
void jit_debugger_step(jit_debugger_t dbg, jit_debugger_thread_id_t thread)
{
jit_debugger_thread_t th;
lock_debugger(dbg);
th = get_specific_thread(dbg, thread);
if(th && th->run_type == JIT_RUN_TYPE_STOPPED)
{
th->run_type = JIT_RUN_TYPE_STEP;
wakeup_all(dbg);
}
unlock_debugger(dbg);
}
/*@
* @deftypefun void jit_debugger_next (jit_debugger_t @var{dbg}, jit_debugger_thread_id_t @var{thread})
* Step over a single line of code but do not step into method calls.
* The request will be ignored if the thread is currently running.
* @end deftypefun
@*/
void jit_debugger_next(jit_debugger_t dbg, jit_debugger_thread_id_t thread)
{
jit_debugger_thread_t th;
lock_debugger(dbg);
th = get_specific_thread(dbg, thread);
if(th && th->run_type == JIT_RUN_TYPE_STOPPED)
{
th->run_type = JIT_RUN_TYPE_NEXT;
wakeup_all(dbg);
}
unlock_debugger(dbg);
( run in 1.701 second using v1.01-cache-2.11-cpan-796a6f069b2 )