[#109403] [Ruby master Feature#18951] Object#with to set and restore attributes around a block — "byroot (Jean Boussier)" <noreply@...>

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

23 messages 2022/08/01

[#109423] [Ruby master Misc#18954] DevMeeting-2022-08-18 — "mame (Yusuke Endoh)" <noreply@...>

Issue #18954 has been reported by mame (Yusuke Endoh).

10 messages 2022/08/04

[#109449] [Ruby master Feature#18959] Handle gracefully nil kwargs eg. **nil — "LevLukomskyi (Lev Lukomskyi)" <noreply@...>

Issue #18959 has been reported by LevLukomskyi (Lev Lukomskyi).

27 messages 2022/08/08

[#109456] [Ruby master Bug#18960] Module#using raises RuntimeError when called at toplevel from wrapped script — "shioyama (Chris Salzberg)" <noreply@...>

Issue #18960 has been reported by shioyama (Chris Salzberg).

15 messages 2022/08/09

[#109550] [Ruby master Feature#18965] Further Thread::Queue improvements — "byroot (Jean Boussier)" <noreply@...>

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

14 messages 2022/08/18

[#109575] [Ruby master Bug#18967] Segmentation fault in stackprof with Ruby 2.7.6 — "RubyBugs (A Nonymous)" <noreply@...>

Issue #18967 has been reported by RubyBugs (A Nonymous).

10 messages 2022/08/19

[#109598] [Ruby master Bug#18970] CRuby adds an invalid header to bin/bundle (and others) which makes it unusable in Bash on Windows — "Eregon (Benoit Daloze)" <noreply@...>

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

17 messages 2022/08/20

[#109645] [Ruby master Bug#18973] Kernel#sprintf: %c allows codepoints above 127 for 7-bits ASCII encoding — "andrykonchin (Andrew Konchin)" <noreply@...>

Issue #18973 has been reported by andrykonchin (Andrew Konchin).

8 messages 2022/08/23

[#109689] [Ruby master Misc#18977] DevMeeting-2022-09-22 — "mame (Yusuke Endoh)" <noreply@...>

Issue #18977 has been reported by mame (Yusuke Endoh).

16 messages 2022/08/25

[#109707] [Ruby master Feature#18980] Re-reconsider numbered parameters: `it` as a default block parameter — "k0kubun (Takashi Kokubun)" <noreply@...>

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

40 messages 2022/08/26

[#109756] [Ruby master Feature#18982] Add an `exception: false` argument for Queue#push, Queue#pop, SizedQueue#push and SizedQueue#pop — "byroot (Jean Boussier)" <noreply@...>

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

11 messages 2022/08/29

[#109773] [Ruby master Misc#18984] Doc for Range#size for Float/Rational does not make sense — "masasakano (Masa Sakano)" <noreply@...>

Issue #18984 has been reported by masasakano (Masa Sakano).

7 messages 2022/08/29

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

From: "ianks (Ian Ker-Seymer)" <noreply@...>
Date: 2022-08-02 17:48:02 UTC
List: ruby-core #109416
Issue #18910 has been updated by ianks (Ian Ker-Seymer).


eightbitraptor (Matthew Valentine-House) wrote in #note-2:
> 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-98566

* 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

Prev Next