ruby-changes:67832
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:02:32 +0900 (JST)
Subject: [ruby-changes:67832] 6420db8ab7 (master): include/ruby/debug.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=6420db8ab7 From 6420db8ab72e3348d0ddf59071c696cbdb270818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Mon, 6 Sep 2021 23:32:23 +0900 Subject: include/ruby/debug.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/debug.h | 555 ++++++++++++++++++++++++++++++++++++++++++++++++++- vm_trace.c | 30 --- 2 files changed, 548 insertions(+), 37 deletions(-) diff --git a/include/ruby/debug.h b/include/ruby/debug.h index 16891e8..c88da9c 100644 --- a/include/ruby/debug.h +++ b/include/ruby/debug.h @@ -10,6 +10,8 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/debug.h#L10 * modify this file, provided that the conditions mentioned in the * file COPYING are met. Consult the file for details. */ +#include "ruby/internal/attr/nonnull.h" +#include "ruby/internal/attr/returns_nonnull.h" #include "ruby/internal/dllexport.h" #include "ruby/internal/event.h" #include "ruby/internal/value.h" @@ -19,74 +21,611 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() https://github.com/ruby/ruby/blob/trunk/include/ruby/debug.h#L21 /* Note: This file contains experimental APIs. */ /* APIs can be replaced at Ruby 2.0.1 or later */ +/** + * @name Frame-profiling APIs + * + * @{ + */ -/* profile frames APIs */ +RBIMPL_ATTR_NONNULL((3)) +/** + * Queries mysterious "frame"s of the given range. + * + * The returned values are opaque backtrace pointers, which you are allowed to + * issue a very limited set of operations listed below. Don't call arbitrary + * ruby methods. + * + * @param[in] start Start position (0 means the topmost). + * @param[in] limit Number objects of `buff`. + * @param[out] buff Return buffer. + * @param[out] lines Return buffer. + * @return Number of objects filled into `buff`. + * @post `buff` is filled with backtrace pointers. + * @post `lines` is filled with `__LINE__` of each backtraces. + * + * @internal + * + * @shyouhei doesn't like this abuse of ::VALUE. It should have been + * `const struct rb_callable_method_entry_struct *`. + */ int rb_profile_frames(int start, int limit, VALUE *buff, int *lines); + +/** + * Queries the path of the passed backtrace. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil The frame is implemented in C etc. + * @retval otherwise Where `frame` is running. + */ VALUE rb_profile_frame_path(VALUE frame); + +/** + * Identical to rb_profile_frame_path(), except it tries to expand the + * returning path. In case the path is `require`-d from something else + * rb_profile_frame_path() can return relative paths. This one tries to avoid + * that. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval "<cfunc>" The frame is in C. + * @retval RUBY_Qnil Can't infer real path (inside of `eval` etc.). + * @retval otherwise Where `frame` is running. + */ VALUE rb_profile_frame_absolute_path(VALUE frame); + +/** + * Queries human-readable "label" string. This is `"<main>"` for the toplevel, + * `"<compiled>"` for evaluated ones, method name for methods, class name for + * classes. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil Can't infer the label (C etc.). + * @retval "<main>" The frame is global toplevel. + * @retval "<compiled>" The frame is dynamic. + * @retval otherwise Label of the frame. + */ VALUE rb_profile_frame_label(VALUE frame); + +/** + * Identical to rb_profile_frame_label(), except it does not "qualify" the + * result. Consider the following backtrace: + * + * ```ruby + * def bar + * caller_locations + * end + * + * def foo + * [1].map { bar }.first + * end + * + * obj = foo.first + * obj.label # => "block in foo" + * obj.base_label # => "foo" + * ``` + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil Can't infer the label (C etc.). + * @retval "<main>" The frame is global toplevel. + * @retval "<compiled>" The frame is dynamic. + * @retval otherwise Base label of the frame. + */ VALUE rb_profile_frame_base_label(VALUE frame); + +/** + * Identical to rb_profile_frame_label(), except it returns a qualified result. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil Can't infer the label (C etc.). + * @retval "<main>" The frame is global toplevel. + * @retval "<compiled>" The frame is dynamic. + * @retval otherwise Qualified label of the frame. + * + * @internal + * + * As of writing there is no way to obtain this return value from a Ruby + * script. This may change in future (it took 8 years and still no progress, + * though). + */ VALUE rb_profile_frame_full_label(VALUE frame); + +/** + * Queries the first line of the method of the passed frame pointer. Can be + * handy when for instance a debugger want to display the frame in question. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil Can't infer the line (C etc.). + * @retval otherwise Line number of the method in question. + */ VALUE rb_profile_frame_first_lineno(VALUE frame); + +/** + * Queries the class path of the method that the passed frame represents. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil Can't infer the class (global toplevel etc.). + * @retval otherwise Class path as in rb_class_path(). + */ VALUE rb_profile_frame_classpath(VALUE frame); + +/** + * Queries if the method of the passed frame is a singleton class. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qtrue It is a singleton method. + * @retval RUBY_Qfalse Otherwise (normal method/non-method). + */ VALUE rb_profile_frame_singleton_method_p(VALUE frame); + +/** + * Queries the name of the method of the passed frame. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil The frame in question is not a method. + * @retval otherwise Name of the method of the frame. + */ VALUE rb_profile_frame_method_name(VALUE frame); + +/** + * Identical to rb_profile_frame_method_name(), except it "qualifies" the + * return value with its defining class. + * + * @param[in] frame What rb_profile_frames() returned. + * @retval RUBY_Qnil The frame in question is not a method. + * @retval otherwise Qualified name of the method of the frame. + */ VALUE rb_profile_frame_qualified_method_name(VALUE frame); -/* debug inspector APIs */ +/** @} */ + +/** + * @name Debug inspector APIs + * + * @{ + */ + +/** Opaque struct representing a debug inspector. */ typedef struct rb_debug_inspector_struct rb_debug_inspector_t; -typedef VALUE (*rb_debug_inspector_func_t)(const rb_debug_inspector_t *, void *); +/** + * Type of the callback function passed to rb_debug_inspector_open(). + * Inspection shall happen only inside of them. The passed pointers gets + * invalidated once after the callback returns. + * + * @param[in] dc A debug context. + * @param[in,out] data What was passed to rb_debug_inspector_open(). + * @return What would be the return value of rb_debug_inspector_open(). + */ +typedef VALUE (*rb_debug_inspector_func_t)(const rb_debug_inspector_t *dc, void *data); + +/** + * Prepares, executes, then cleans up a debug session. + * + * @param[in] func A callback to run inside of a debug session. + * @param[in,out] data Passed as-is to `func`. + * @return What was returned from `func`. + */ VALUE rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data); + +/** + * Queries the current receiver of the passed context's upper frame. + * + * @param[in] dc A debug context. + * @param[in] index Index of the frame from top to bottom. + * @exception rb_eArgError `index` out of range. + * @return The current receiver at `index`-th frame. + */ VALUE rb_debug_inspector_frame_self_get(const rb_debug_inspector_t *dc, long index); + +/** + * Queries the current class of the passed context's upper frame. + * + * @param[in] dc A debug context. + * @param[in] index Index of the frame from top to bottom. + * @exception rb_eArgError `index` out of range. + * @return The current class at `index`-th frame. + */ VALUE rb_debug_inspector_frame_class_get(const rb_debug_inspector_t *dc, long index); + +/** + * Queries the binding of the passed context's upper frame. + * + * @param[in] dc A debug context. + * @param[in] index Index of the frame from top to bottom. + * @exception rb_eArgError `index` out of range. + * @return The binding at `index`-th frame. + */ VALUE rb_debug_inspector_frame_binding_get(const rb_debug_inspector_t *dc, long index); + +/** + * Queries the instruction sequence of the passed context's upper frame. + * + * @param[in] dc A debug context. + * @param[in] index Index of the frame from top to bottom. + * @exception rb_eArgError `index` out of range. + * @retval RUBY_Qnil `index`-th frame is not in Ruby (C etc.). + * @retval otherwise An instance of `RubyVM::InstructionSequence` which + * represents the instruction sequence at `index`-th + * frame. + */ VALUE rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index); + +/** + * Queries the backtrace object of the context. This is as if you call + * `caller_locations` at the point of debugger. + * + * @param[in] dc A debug context. + * @return An array of `Thread::Backtrace::Location` which represents the + * current point of execution at `dc`. + + */ VALUE rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc); (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/