From 5b18f2988ebbdc7391b618638dd13910cbb4a857 Mon Sep 17 00:00:00 2001 From: Brendan Weibrecht Date: Thu, 25 Jun 2020 02:56:07 +1000 Subject: [PATCH] Fix require failing in Termux on Android Note that this change does not make rbtrace *actually* work in Termux - it just allows an app to start up without an exception when it has `require 'rbtrace'`. The exception is: ``` $ ruby -r rbtrace -e puts Traceback (most recent call last): 1: from /data/data/com.termux/files/usr/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' /data/data/com.termux/files/usr/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- rbtrace (LoadError) 2: from /data/data/com.termux/files/usr/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:34:in `require' 1: from /data/data/com.termux/files/usr/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:130:in `rescue in require' /data/data/com.termux/files/usr/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:130:in `require': dlopen failed: cannot locate symbol "rindex" referenced by "/data/data/com.termux/files/usr/lib/ruby/gems/2.6.0/gems/rbtrace-0.4.13/lib/rbtrace.so"... - /data/data/com.termux/files/usr/lib/ruby/gems/2.6.0/gems/rbtrace-0.4.13/lib/rbtrace.so (LoadError) ``` It turns out that Android (9, at least) does not include `rindex` - I believe because it has been [deprecated](https://linux.die.net/man/3/rindex) for many years; `strrchr` is apparently a drop-in replacement. After that, there was another exception about the `SUN_LEN` symbol missing. I added [this definition](https://stackoverflow.com/a/12628469) for the macro. That then got the gem able to be required without error. I would have liked to get rbtrace working in Termux, but this is as far as I've been able to progress for now. I'm having trouble with the `ipcs` binary. It's [deliberately not provided by Termux's `util-linux` package](https://github.com/termux/termux-packages/blob/8076aec21f8d4b0dd5f880af1af467961dcbbbbb/packages/util-linux/build.sh#L19) for some reason. With root, I can run Stericson Busybox's `ipcs`, but it just returns this: ``` $ su -c /sbin/ipcs kernel not configured for message queues kernel not configured for shared memory kernel not configured for semaphores ``` I'm hoping that's not just a quirk of the particular kernel on [my device](https://www.indiegogo.com/projects/cosmo-communicator). But perhaps the shared memory functionality is not actually suppported on Android? I don't yet know. Anyway. `test.sh` does not work since rbtrace itself does not yet work on Android. The tmpdir change in there gets it one step closer at least - `/tmp` does not exist on Android. This commit was tested by simply: ```bash $ gem build rbtrace.gemspec && gem install rbtrace-0.4.13.gem && ruby -r rbtrace -e puts ``` --- ext/rbtrace.c | 9 +++++++-- server.rb | 23 +++++++++++++---------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ext/rbtrace.c b/ext/rbtrace.c index b145f28..58125f0 100644 --- a/ext/rbtrace.c +++ b/ext/rbtrace.c @@ -51,6 +51,11 @@ #endif +// The SUN_LEN macro is not available on Android +#ifndef SUN_LEN +#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path)) +#endif + static uint64_t ru_utime_usec() { @@ -688,7 +693,7 @@ rbtracer_add(char *query, bool is_slow) *idx = NULL, *method = NULL; - if (NULL != (idx = rindex(query, '.'))) { + if (NULL != (idx = strrchr(query, '.'))) { klass_begin = 0; klass_end = idx - query; is_singleton = true; @@ -700,7 +705,7 @@ rbtracer_add(char *query, bool is_slow) method = idx+1; - } else if (NULL != (idx = rindex(query, '#'))) { + } else if (NULL != (idx = strrchr(query, '#'))) { klass_begin = 0; klass_end = idx - query; is_singleton = false; diff --git a/server.rb b/server.rb index d0e5a1c..af86940 100644 --- a/server.rb +++ b/server.rb @@ -1,4 +1,5 @@ require 'ext/rbtrace' +require 'tmpdir' class String def multiply_vowels(num) @@ -26,19 +27,21 @@ def self.run while true proc { - Dir.chdir("/tmp") do - Dir.pwd - Process.pid - 'hello'.multiply_vowels(3){ :ohai } - sleep rand*0.5 + Dir.mktmpdir do |tmp| + Dir.chdir(tmp) do + Dir.pwd + Process.pid + 'hello'.multiply_vowels(3){ :ohai } + sleep rand*0.5 - ENV['blah'] - GC.start + ENV['blah'] + GC.start - reload_test.call - Test.run + reload_test.call + Test.run - #fib(1024*100) + #fib(1024*100) + end end }.call end