<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Frederick Cheung</title>
    <description>The latest articles on DEV Community by Frederick Cheung (@fcheung).</description>
    <link>https://dev.to/fcheung</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F276472%2F91de3375-4e72-4a60-b381-842c02b01d30.jpeg</url>
      <title>DEV Community: Frederick Cheung</title>
      <link>https://dev.to/fcheung</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fcheung"/>
    <language>en</language>
    <item>
      <title>AWS Lambda Layers and Ruby</title>
      <dc:creator>Frederick Cheung</dc:creator>
      <pubDate>Sun, 29 Nov 2020 14:31:41 +0000</pubDate>
      <link>https://dev.to/fcheung/aws-lambda-layers-and-ruby-3ki7</link>
      <guid>https://dev.to/fcheung/aws-lambda-layers-and-ruby-3ki7</guid>
      <description>&lt;p&gt;I've been building a few things using lambda functions in ruby recently. Some of these are just standalone functions, some end up as more complicated stacks, with multiple functions working together, usually with a lot of common dependencies.&lt;/p&gt;

&lt;p&gt;This was annoying to work with since on each &lt;code&gt;sam build&lt;/code&gt; invocation bundler was redownloading &amp;amp; reinstalling these dependencies for each function, &lt;br&gt;
even if you had only changed one of the functions. By the time I got to 4-5 functions in a stack it was really starting to slow down that fast iteration&lt;br&gt;
that is so beneficial. This got me thinking - could I put the vendored bundle in a layer that was used by all my functions?&lt;/p&gt;


&lt;h2&gt;
  
  
  One Gemfile to rule them all
&lt;/h2&gt;

&lt;p&gt;At the start my directory looked at little like this - the standard sam setup &lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── Gemfile
├── Gemfile.lock
├── function1
│   ├── Gemfile
│   ├── Gemfile.lock
│   └── app.rb
├── function2
│   ├── Gemfile
│   ├── Gemfile.lock
│   └── app.rb
└── template.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing I did was merge the Gemfiles into a single one that I could use to build the layer. In order to make sure this would never diverge from what the functions are using, I added this at the top level and symlinked it into each function &lt;sup id="fnref2"&gt;2&lt;/sup&gt;. I then added a folder called &lt;code&gt;dependencies&lt;/code&gt; for my layer, containing just the Gemfile and Gemfile.lock (also as symlinks), and added the layer itself to the template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::LayerVersion&lt;/span&gt;
  &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;LayerName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${AWS::StackName}-dependencies"&lt;/span&gt;
    &lt;span class="na"&gt;ContentUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dependencies/&lt;/span&gt;
    &lt;span class="na"&gt;CompatibleRuntimes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ruby2.7&lt;/span&gt;
    &lt;span class="na"&gt;LicenseInfo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;MIT'&lt;/span&gt;
    &lt;span class="na"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Retain&lt;/span&gt;
  &lt;span class="na"&gt;Metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;BuildMethod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby2.7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each function needs to be told to use this new layer, by adding this to its properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Layers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;Dependencies&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sam build&lt;/code&gt; / &lt;code&gt;sam deploy&lt;/code&gt; ran ok - this all seems too easy!&lt;/p&gt;

&lt;h2&gt;
  
  
  Trouble in paradise
&lt;/h2&gt;

&lt;p&gt;Unfortunately I've simultaneously broken things and made them slower:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sam build&lt;/code&gt; still wants to run bundler in each of my function directories&lt;/li&gt;
&lt;li&gt;The layer doesn't put gems where ruby is looking for them (see &lt;a href="https://github.com/aws/aws-lambda-builders/issues/177"&gt;this issue&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;The layer installed all the gems, including test/development ones&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's tempting to fix the first issue by just removing the Gemfile from each function, but I didn't want to do that - I really value bundler&lt;br&gt;
enforcing that the correct versions of gems and ruby are installed and the work it does to avoid various forms of dependency hell. &lt;/p&gt;

&lt;p&gt;Luckily there is a way out: while &lt;code&gt;sam build&lt;/code&gt; has a default way of building functions for a given runtime (i.e. run bundler for ruby, pip for python etc.) you can override this by setting the build method to 'makefile', in which case it will just run make instead. This is most useful for &lt;a&gt;custom runtimes&lt;/a&gt; but pretty handy here too.&lt;/p&gt;

&lt;p&gt;This results in functions that look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Function1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
  &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;function1/&lt;/span&gt;
    &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app.lambda_handler&lt;/span&gt;
    &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby2.7&lt;/span&gt;
    &lt;span class="na"&gt;Layers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;Dependencies&lt;/span&gt;
  &lt;span class="na"&gt;Metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;BuildMethod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;makefile'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a Makefile (in the directory for the function) that just copies the source into the destination directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;build-Function1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;cp&lt;/span&gt; &lt;span class="err"&gt;-pLR&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"$(ARTIFACTS_DIR)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do end up with a bunch of nearly identical makefiles, which is a bit tedious but ok. Don't forget that makefiles need to use tabs, not spaces!&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding &lt;del&gt;Nemo&lt;/del&gt; Rubygems
&lt;/h2&gt;

&lt;p&gt;While researching the second issue I came across a &lt;a href="https://iamjkahn.com/2020/09/update-to-building-lambda-layers-with-aws-sam.html"&gt;post&lt;/a&gt;&lt;br&gt;
by Josh Kahn that seemed to do exactly what I wanted: it builds the layer using a custom makefile that runs bundler and then moves the output around so that the gems are in ruby's search path.&lt;/p&gt;

&lt;p&gt;This was so close to what I wanted! Unfortunately we have some private code that we install as gems build from git, so that approach doesn't quite work - you need to preserve more of bundler's structure. I ended up letting mostly bundler just do its thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;build-Dependencies&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="nv"&gt;BUNDLE_WITHOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"development:test"&lt;/span&gt; bundle &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="s2"&gt;"--path=&lt;/span&gt;&lt;span class="nv"&gt;$(ARTIFACTS_DIR)&lt;/span&gt;&lt;span class="s2"&gt;/ruby/lib/vendor/bundle"&lt;/span&gt;
  &lt;span class="err"&gt;rm&lt;/span&gt; &lt;span class="err"&gt;-rf&lt;/span&gt; &lt;span class="s2"&gt;"$(ARTIFACTS_DIR)/ruby/lib/vendor/bundle/ruby/2.7.0/cache"&lt;/span&gt;
  &lt;span class="err"&gt;rm&lt;/span&gt; &lt;span class="err"&gt;-rf&lt;/span&gt; &lt;span class="s2"&gt;"$(ARTIFACTS_DIR)/ruby/lib/vendor/bundle/ruby/2.7.0/bin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses &lt;code&gt;BUNDLE_WITHOUT&lt;/code&gt; to avoid installing unneeded gems and &lt;code&gt;--path&lt;/code&gt;  to control the install location. The last two &lt;code&gt;rm-rf&lt;/code&gt; steps just make the deployment package a little smaller by removing unneeded files.&lt;/p&gt;

&lt;p&gt;On its own this isn't quite enough, because the lambda function can't see the gems. It also doesn't know that it shouldn't expect to find the development / test only gems, so it will complain about that too. The magic step is to create .bundle/config in each of the lambda functions with these contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;BUNDLE_DEPLOYMENT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
&lt;span class="na"&gt;BUNDLE_WITHOUT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;development:test"&lt;/span&gt;
&lt;span class="na"&gt;BUNDLE_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/ruby/lib/vendor/bundle"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Puts bundler into deployment mode, so that it will complain if Gemfile and Gemfile.lock are out of sync&lt;/li&gt;
&lt;li&gt;Tells bundler to ignore gems in development / test groups&lt;/li&gt;
&lt;li&gt;Tells bundler where gems have been installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's it - with this the lambda function is able to load the gems from the layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I'm pretty happy with this - it achieved all the goals I had when I started out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One consistent gemfile across functions and in production vs running specs locally&lt;/li&gt;
&lt;li&gt;Bundler runs once only per invocation of &lt;code&gt;sam build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Bundler still enforcing gem versions etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined with the recent &lt;code&gt;sam build --cached&lt;/code&gt; feature (sam 1.9.0 and higher) it gets even better: bundler is only run if Gemfile/Gemfile.lock has changed. While &lt;code&gt;--cached&lt;/code&gt; is cool all on its own, without dependencies isolated in this fashion, it would run bundler for each function where at least one file has changed (since &lt;code&gt;sam&lt;/code&gt; has&lt;br&gt;
no knowledge of what file changes should trigger bundler).&lt;/p&gt;

&lt;p&gt;If you want to play around with this, I've made a &lt;a href="https://github.com/fcheung/layer-demo"&gt;very simple repo&lt;/a&gt; that demonstrates this.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I don't love the separate gemfiles. More than once I've added something to the toplevel gemfile (used for running specs) but not the per function Gemfile, so although my specs were green the dependiences weren't correct when deployed. I've also made mistakes because the per function Gemfiles have a ruby constraint but the top level one didn't, or having 2 functions accidentally end up with different versions of the same dependency. While in theory there's nothing wrong with this, I find it a lot easier if those variations between functions don't exist. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;These symlinks will break if you need to run &lt;code&gt;sam build -u&lt;/code&gt; - my workaround is to run the entire sam build process in docker (and not pass &lt;code&gt;-u&lt;/code&gt; at all). ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>ruby</category>
      <category>aws</category>
    </item>
    <item>
      <title>Diagnosing a mruby crash</title>
      <dc:creator>Frederick Cheung</dc:creator>
      <pubDate>Sat, 04 Jan 2020 18:23:42 +0000</pubDate>
      <link>https://dev.to/fcheung/diagnosing-a-mruby-crash-37pn</link>
      <guid>https://dev.to/fcheung/diagnosing-a-mruby-crash-37pn</guid>
      <description>&lt;p&gt;I've been playing with mruby recently, after seeing several interesting talks at Rubyconf 2019. I found a few projects ( &lt;a href="https://github.com/mruby-esp32/mruby-esp32"&gt;mruby-esp32&lt;/a&gt;, &lt;a href="https://github.com/mimaki/M5Stack-mruby"&gt;M5Stack-mruby&lt;/a&gt;) that were setup for building mruby on the device I had bought (an M5StickC), so after some messing around with toolchains &amp;amp; drivers I was up and running. &lt;/p&gt;

&lt;p&gt;All these projects were using mruby 2.0.1 (released April 2019), but I wanted to use mruby 2.1 (Nov 2019) which has a bunch of ruby 2.6 features, some nice enhancements to the C apis (including keyword arguments) and the usual collection of bugfixes. In theory this was easy to fix: the setup for these projects was a git submodule pointing at mruby, all I needed to do was update that submodule to the tag for 2.1, recompile, and I'd be on my way. &lt;/p&gt;

&lt;p&gt;However, when I did that, my device started crashing as soon as it loaded mruby (in the call to &lt;code&gt;mrb_open&lt;/code&gt;) with a message like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x000ef970  PS      : 0x00060730  A0      : 0x800e791d  A1      : 0x3ffb8c40  
A2      : 0x3ffb8d30  A3      : 0x3ffb8c60  A4      : 0x0000000e  A5      : 0x000ef970  
A6      : 0x00000001  A7      : 0x3ffb4a68  A8      : 0x800e7cf0  A9      : 0x00000000  
A10     : 0x3ffb4a68  A11     : 0x00000010  A12     : 0x3ffb5298  A13     : 0x3ffb4a68  
A14     : 0x00000012  A15     : 0x00000002  SAR     : 0x0000000f  EXCCAUSE: 0x00000014  
EXCVADDR: 0x000ef970  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000  

ELF file SHA256: 5da51cd84380674eb796b51bd0d21ea3ee3c4f275043c281291ffd060f6d7e00

Backtrace: 0x000ef970:0x3ffb8c40 0x400e791a:0x3ffb8d70 0x400e7e33:0x3ffb8ea0 0x400d6ca1:0x3ffb8f30 0x400efb3d:0x3ffb8fb0 0x400f0ad9:0x3ffb9000 0x400da57f:0x3ffb9060 0x400da32b:0x3ffb9080 0x400da341:0x3ffb90a0 0x400da361:0x3ffb90c0 0x400d390d:0x3ffb90e0 0x40086ee9:0x3ffb9150
0x400e791a: mrb_funcall_with_block at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/vm.c:808 (discriminator 8)

0x400e7e33: mrb_funcall_argv at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/vm.c:808 (discriminator 8)

0x400d6ca1: mrb_obj_new at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/class.c:504

0x400efb3d: mrb_exc_new_str at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/error.c:563

0x400f0ad9: mrb_init_exception at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/error.c:610

0x400da57f: mrb_init_core at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/init.c:42

0x400da32b: mrb_open_core at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/state.c:43

0x400da341: mrb_open_allocf at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/state.c:71

0x400da361: mrb_open at /Users/fred/iot/M5Stick-mruby/components/mruby_component/mruby/src/state.c:63

0x400d390d: mrubyTask(void*) at /Users/fred/iot/M5Stick-mruby/main/main.cpp:38

0x40086ee9: vPortTaskWrapper at /Users/fred/iot/esp-idf/components/freertos/port.c:403
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which was more than a little intimidating, seeing as I'm totally unfamiliar with the mrb or the mrb source and my google searches turned up nothing. It's crashing inside &lt;code&gt;mrb_funcall_with_block&lt;/code&gt;, which is the c api function for calling a ruby method, but that's about all I could glean from the stack trace.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bisect to the rescue
&lt;/h1&gt;

&lt;p&gt;That's when I remembered a great talk from &lt;a href="https://brightonruby.com/2019/you-may-have-encountered-a-bug-in-the-ruby-interpreter-alyssa-ross/"&gt;Brighton Ruby 2019&lt;/a&gt; about tracking down a bug in MRI. Different codebase, same idea: just git bisect on the mruby itself, with the 2.0.1 tag as the initial "good" commit and 2.1.0 as the bad one.&lt;/p&gt;

&lt;p&gt;For those unfamiliar with git bisect, it's an awesome tool, well worth adding to your arsenal. Given an initial pair of good and bad commits it will do a binary search through the intervening history to find the commit that caused the problem. Since it's doing a binary search, instead of having to try all 900 or so commits between the 2 mruby versions, I would only need to try 10 or so (which was a good thing, since you're recompiling mruby at each step). I couldn't quite do the automated setup Alyssa did in her talk: I had to manually build my code &amp;amp; flash to the device for each commit git bisect asked me to check. I also got compile errors on some commits and had to include the fix from &lt;a href="https://github.com/mruby/mruby/commit/fa85f91e0e3ebff7b2626bfcf550821445c064d7"&gt;this commit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Still it wasn't too long before it pointed the finger of blame at &lt;a href="https://github.com/mruby/mruby/commit/2256bb07b02c9025ed7ea1fee8c21c86104c07dc"&gt;this commit&lt;/a&gt;. This was a change relating to an optimisation relating to how methods are represented. &lt;/p&gt;

&lt;h1&gt;
  
  
  Digging deeper
&lt;/h1&gt;

&lt;p&gt;On mruby, a ruby method is represented by two things: a pointer to a function or RProc structure and some flags. Those flags tell ruby whether the pointer is a function pointer or not and whether the method takes arguments. There are only 2 flags (i.e. 2 bits are needed) and on most platforms function pointers are 4 byte aligned: the low 2 bits are never used. Therefore mruby can use those 2 bits to store the flags. As a result it doesn't need to allocate a separate data structure, reduces memory accesses required to call methods etc. (A similar trick is used to encode integers into fixnum objects).&lt;/p&gt;

&lt;p&gt;When mruby gets a &lt;code&gt;mrb_method_t&lt;/code&gt; (the name of this data type) it can mask off the low 2 bits to get that pointer or the high bits to get the flag information.&lt;/p&gt;

&lt;p&gt;If however function pointers are not 4 byte aligned though things will go very wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When jumping to the function, mruby ignores the last 2 bits, so will use the wrong pointer value&lt;/li&gt;
&lt;li&gt;The low bits look like flags so mruby may use the pointer incorrectly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apparently that's the case on my platform (you can see this on the stack trace above - the addresses are not all divisible by zero). Prior to the linked commit you had to opt into this optimisation, but afterwards it became the default.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fixing it
&lt;/h1&gt;

&lt;p&gt;Luckily the commit message had all the information I needed: you can disable the optimization by adding &lt;code&gt;MRB_METHOD_T_STRUCT&lt;/code&gt; to the list of defines in the mruby build config file (compiling with falign-functions=4 didn't seem to do anything). With that, I was up and running on mruby 2.1.&lt;/p&gt;

&lt;p&gt;This option is also documented in the mrbconf docs, however I doubt I would have realised its significance.&lt;/p&gt;

&lt;p&gt;So there you have it: mruby is cool and so git bisect is a great tool even if you don't understand the codebase. (and go watch Alyssa's talk if you have a spare 25 minutes or so - I saw it in person and it is well worth the watch)&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>mruby</category>
    </item>
    <item>
      <title>My first RubyConf</title>
      <dc:creator>Frederick Cheung</dc:creator>
      <pubDate>Thu, 21 Nov 2019 19:25:31 +0000</pubDate>
      <link>https://dev.to/fcheung/my-first-rubyconf-2nfi</link>
      <guid>https://dev.to/fcheung/my-first-rubyconf-2nfi</guid>
      <description>&lt;p&gt;It's been a week of firsts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;my first visit to RubyConf&lt;/li&gt;
&lt;li&gt;my first talk at RubyConf&lt;/li&gt;
&lt;li&gt;my first time being a guide at a conference&lt;/li&gt;
&lt;li&gt;and now, my first post on dev.to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've been a member of the ruby community for a long time now, back when 1.8.4 was all the rage, threads were still green and deploying rails applications involved mod_fastcgi / mod_fcgi and large amounts of hopes and prayers. Somehow I'd never made it to RubyConf, although I've had my share of RailsConfs and some of the european ruby conferences.&lt;/p&gt;

&lt;p&gt;I don't have a reference point, but RubyConf 2019 was an all-round excellent experience.&lt;/p&gt;

&lt;h1&gt;
  
  
  Speaking at RubyConf
&lt;/h1&gt;

&lt;p&gt;I was the usual mixture of nerves and excitement - I knew I had prepared to the best of my ability, but like many, public speaking is definitely pushing myself outside of my comfort zone. The speakers' reception was a really nice way to chat to many of my fellow speakers &amp;amp; pick up a few tips (@molly_struve is a font of wisdom, on top of being a great runner!). There's always some comfort too in seeing that everyone else is nervous too!&lt;/p&gt;

&lt;p&gt;After some AV shenanigans involving USB-C to HDMI dongles that were only just fixed in time, the talk itself went pretty smoothly. At the speakers' reception one speaker mentioned they'd stopped using speaker notes ever since an unfortunate setup incident meant they had to do without. Like many others, I was horrified at the thought but I genuinely think that I didn't actually use mine - more of an emotional crutch than anything else (I probably would have freaked out if I didn't have them though!).&lt;/p&gt;

&lt;p&gt;Everyone I spoke to afterwards was really nice about the talk and &lt;a class="comment-mentioned-user" href="https://dev.to/annarankin"&gt;@annarankin&lt;/a&gt;
 even made some lovely &lt;a href="https://twitter.com/anniesqueedle/status/1197013136055918593?s=12"&gt;sketch notes&lt;/a&gt;, so I'm chalking that up as success.&lt;/p&gt;

&lt;h1&gt;
  
  
  Guiding at RubyConf
&lt;/h1&gt;

&lt;p&gt;Every year a certain number of opportunity scholars (I'm told 20 is typical) get a free ticket + travel expenses to go to RubyConf. They're all paired with a guide, who's a friendly face &amp;amp; direct point of contact during the conference. It's a really well run program, with about the right balance of structure vs freedom. &lt;/p&gt;

&lt;p&gt;Although 20 scholars + 20 guides + some organisers adds up to a lot of people, we were split up into cohorts that were much more manageable. We had some great discussions on jobs, speaking and more ( I definitely picked up a few tips!).&lt;/p&gt;

&lt;p&gt;I later realised that fellow speaker Ben Greenberg was an opportunity scholar just 2 years ago (see &lt;a href="https://dev.to/benhayehudi/beignets-sharks-and-ruby-my-week-at-rubyconf-c9g"&gt;his writeup&lt;/a&gt; from back then) - so cool to see the leaps people make! I loved the way that after just a short while my scholar was striding up to speakers for questions &amp;amp; stickers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Talks at RubyConf
&lt;/h1&gt;

&lt;p&gt;Picking which talk to go was a struggle - most slots I was torn between at least 2-3 options! There was an amazing range, from Sandi Metz's incredible "Lucky you" on social mobility and the unfairness that is just baked into the system, to life deep in the ocean sediment or livecoding in ruby on an apple ][.&lt;/p&gt;

&lt;p&gt;I went to quite a few mruby talks, more out of curiosity than anything else and have ended up buying a small microcontroller (the m5stickC that featured in talk on mruby's init sequence) to play with!&lt;/p&gt;

&lt;p&gt;All in all the lineup was really strong, and I feel honoured to have been part of it.&lt;/p&gt;

&lt;h1&gt;
  
  
  People at RubyConf
&lt;/h1&gt;

&lt;p&gt;I wasn't on top form, between jetlag, a cold/headache that I never really shook and pre talk nerves followed by post talk crash, but I still enjoyed hanging out with some fun people, walking around East Nashville \u0026 chatting about all sorts of topics.&lt;/p&gt;

&lt;p&gt;Ruby is an amazing community to be a part of and I love seeing the positive impact it has had on so many others too. I'll be back for sure!&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
  </channel>
</rss>
