Given various assumptions about your setup, provides
Method#c_location, which is the
Method#source_location for methods that were written in C.
On Mac OS X, you will need the
nm tool that's bundled with Xcode; and the
tool that you can get with
brew install binutils.
On Linux you'll need the
objdump tool, on Debian/Ubuntu it's obtainable with
apt-get install binutils, I assume other distros are similar.
On all systems you'll need your Rubies compiled with debug information (seems to be the
default on Linux). If you're using
export rvm_configure_flags="CFLAGS=-g" to
If it still doesn't work — try running the commands that are found in
lib/c_location/resolver.rb manually, and see where the problem is.
How does this even work?!
Find a pointer to the C function that's behind a ruby method (most of the code in
ext/c_location.cdeals with doing this for various versions of Ruby — it's certainly not exposed in the API!)
Find the shared object file that contains this C function, and the offset in that file that the function's compiled code resides. This is done using the non-standard (but widespread)
dladdr()function. (See man
(Mac OS X only). Use
nmto find the original library that the shared object file was built from. (This is because
.bundlefiles don't contain the debugging information directly).
objdumpto read the DWARF data embedded in the shared object file when it was compiled with the
Use some heuristics to guess the directories that might include that file based on the location of the object file on disk, and look for a correctly named file there.
(In short, lots and lots of string).
If possible, it'd be nice to have fewer external calls. Perhaps the data we're using
for could be done in Ruby without too much help; we could even try bundling
avoid the dependency on
It'd be really cool to make the Pry
edit-method command work for C extensions. I think
this is just a matter of writing more code: have
edit-method work as normal, and then
after closing the editor run
make in the right directory; then copy the
.so file into
a new directory and then require it. (the Init_foo method should then just overwrite all
the existing setup).
Released under the MIT License. Bug reports and pull requests welcome.
Do not use this in production :p.