[#109115] [Ruby master Misc#18891] Expand tabs in C code — "k0kubun (Takashi Kokubun)" <noreply@...>

Issue #18891 has been reported by k0kubun (Takashi Kokubun).

13 messages 2022/07/02

[#109118] [Ruby master Bug#18893] Don't redefine memcpy(3) — "alx (Alejandro Colomar)" <noreply@...>

Issue #18893 has been reported by alx (Alejandro Colomar).

11 messages 2022/07/02

[#109152] [Ruby master Bug#18899] Inconsistent argument handling in IO#set_encoding — "javanthropus (Jeremy Bopp)" <noreply@...>

Issue #18899 has been reported by javanthropus (Jeremy Bopp).

10 messages 2022/07/06

[#109193] [Ruby master Bug#18909] ARGF.readlines reads more than current file — "JohanJosefsson (Johan Josefsson)" <noreply@...>

Issue #18909 has been reported by JohanJosefsson (Johan Josefsson).

17 messages 2022/07/13

[#109196] [Ruby master Bug#18911] Process._fork hook point is not called when Process.daemon is used — "ivoanjo (Ivo Anjo)" <noreply@...>

Issue #18911 has been reported by ivoanjo (Ivo Anjo).

9 messages 2022/07/13

[#109201] [Ruby master Bug#18912] Build failure with macOS 13 (Ventura) Beta — "hsbt (Hiroshi SHIBATA)" <noreply@...>

Issue #18912 has been reported by hsbt (Hiroshi SHIBATA).

20 messages 2022/07/14

[#109206] [Ruby master Bug#18914] Segmentation fault during Ruby test suite execution — "jprokop (Jarek Prokop)" <noreply@...>

Issue #18914 has been reported by jprokop (Jarek Prokop).

8 messages 2022/07/14

[#109207] [Ruby master Feature#18915] New error class: NotImplementedYetError or scope change for NotImplementedYet — Quintasan <noreply@...>

Issue #18915 has been reported by Quintasan (Michał Zając).

18 messages 2022/07/14

[#109260] [Ruby master Feature#18930] Officially deprecate class variables — "Eregon (Benoit Daloze)" <noreply@...>

Issue #18930 has been reported by Eregon (Benoit Daloze).

21 messages 2022/07/20

[#109314] [Ruby master Bug#18938] Backport cf7d07570f50ef9c16007019afcff11ba6500d70 — "byroot (Jean Boussier)" <noreply@...>

Issue #18938 has been reported by byroot (Jean Boussier).

8 messages 2022/07/25

[#109371] [Ruby master Feature#18949] Deprecate and remove replicate and dummy encodings — "Eregon (Benoit Daloze)" <noreply@...>

Issue #18949 has been reported by Eregon (Benoit Daloze).

35 messages 2022/07/29

[ruby-core:109357] [Ruby master Feature#18910] Improve maintainability of LLDB helpers

From: "eightbitraptor (Matthew Valentine-House)" <noreply@...>
Date: 2022-07-28 13:03:35 UTC
List: ruby-core #109357
Issue #18910 has been updated by eightbitraptor (Matthew Valentine-House).


ianks (Ian Ker-Seymer) wrote in #note-1:
> On a related note, I’ve often found myself wanting access to these helpers when developing native extensions. I’ve copy-pasta’d them in the past, but I wonder if Ruby could support including them for debug builds?

One thing that I'd like to do in a future PR is experiment with having these LLDB helpers inside a gem. Despite the slightly odd experience of having a Ruby gem that contained only Python code, we'd get a couple of benefits. 1) We'd be able to tie the helpers to a specific version of Ruby - they're very closely coupled to Ruby internals, and can be brittle when implementation details in the VM change. and 2) It would then be more easily usable for folks writing native extensions. What do you think?

----------------------------------------
Feature #18910: Improve maintainability of LLDB helpers
https://bugs.ruby-lang.org/issues/18910#change-98501

* Author: eightbitraptor (Matthew Valentine-House)
* Status: Open
* Priority: Normal
----------------------------------------
**[Github PR: #6129](https://github.com/ruby/ruby/pull/6129)**

## Summary

`lldb_cruby.py` manages lldb custom commands using functions. The file is a large list of Python functions, and an init handler to map some of the Python functions into the debugger, to enable execution of custom logic during a debugging session.

Since LLDB 3.7 (September 2015) there has also been support for using python classes rather than bare functions, as long as those classes implement a specific interface.

This PR Introduces some more defined structure to the LLDB helper functions by switching from the function based implementation to the class based one, and providing an auto-loading mechanism by which new functions can be loaded.

The intention behind this change is to make working with the LLDB helpers easier, by reducing code duplication, providing a consistent structure and a clearer API for developers.

## Background

The current function based approach has some advantages and disadvantages

Advantages:

- Adding new code is easy. 
- All the code is self contained and searchable.

Disadvantages:
- No visible organisation of the file contents. This means
  - Hard to tell which functions are utility functions and which are available to you in a debugging session
  - Lots of code duplication within lldb functions
- Large files quickly become intimidating to work with - for example, `lldb_disasm.py` was implemented as a seperate Python module because it was easier to start with a clean slate than add significant amounts of code to `lldb_cruby.py`

### What are we doing here?

This PR attempts, to fix the disadvantages of the current approach and maintain, or enhance, the benefits. The new structure of a command looks like this;

 ```
# Our class inherits from RbBaseCommand which provides access to Ruby globals
# and utility helpers
 class TestCommand(RbBaseCommand):
    # program is the keyword the user will type in lldb to execute this command
    program = "test"

    # help_string will be displayed in lldb when the user uses the help functions
    help_string = "This is a test command to show how to implement lldb commands"

    # Init is required by the API but we don't need to do anything here
    def __init__(self, debugger, _internal_dict):
        pass

    # call is where our command logic will be implemented
    def __call__(self, debugger, command, exe_ctx, result):

        # this call to super sets up the Ruby globals, ie. everything that currently
        # done by the following code in the current lldb helpers
        #   if not ('RUBY_Qfalse' in globals()):
        #       lldb_init(debugger)
        #
        super().__call__(self, debugger, command, exe_ctx, result)

        # Set up some commonly used variables. Nearly every existing lldb command
        # currently does this by hand.
        target, process, thread, frame = self.build_environment(debugger)

        # rest of our code goes here
  ```

If the command fulfils the following criteria it will then be auto-loaded when an lldb session is started:

- The package file must exist inside the `commands` directory and the filename must end in `_command.py`
- The package must implement a class whose name ends in `Command`
- The class must implement the `lldb` API (at minimum this means defining `__init__` and `__call__`, but also optionally `get_short_help` and `get_long_help`)
- The class must have a class variable `package` that is a String. This is the name of the command you'll call in the `lldb` debugger.

## Advantages/Disadvantages of this approach

Advantages:

- Less code duplication. 
  - We can now use inheritance and mix-ins to provide shared functionality between commands.
  -  Commands are easier to read and reason about, only code relevant to the command behaviour is in `__call__` most everything else can be abstracted away.
- Easier to see at a glance what functions are available, what they do, and what commands they're mapped to, rather than jumping around a large file

Disadvantages

- Slightly more boilerplate code required to add new commands - although I've attempted to mitigate this by providing a template - `commands/command_template.py` that can be copied and renamed to use as a starting point.

## Notes
- Only two smaller commands have been ported to this new structure at the moment: `heap_page`, and `rclass_ext`. I've kept these commits seperate in order to show what work is required to port existing commands over to the new style.
- More commands will be ported over individually in seperate PR's, until eventually we'll have no more function based commands at all and can deprecate them.
- The debugger instance passed to `__call__` is different to the one passed to `__init__` - and attempting to store one in an ivar and use it later doesn't work for me. This means I can't call super in the initialiser to setup the thread variables, and have them exist and work by the time the function is called. I'd like to find a way around this issue and call `super` in the `__init__` to clean up the `__call__` a little more.
       



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread