shared lib loading and in kona

89 views
Skip to first unread message

Neeraj Rai

unread,
May 3, 2013, 12:16:43 AM5/3/13
to kona...@googlegroups.com
Hi,

I came across this example of loading and executing a shared lib (from help \:)
a:`"mylib.so" 2:(`testShared,1); 
a[1]

I tried to create a mylib.so with function testShared taking a single argument (int  a) and returning the kI(1).
To use the k object in my shared lib, I ran into the same problem that I had with c interface.
I ended up copying the kona code base and modifying k.c to take main out and link in myadd.c instead.
using -fPIC for obj flags and -shared for .so flag, I got a .so and was able to execute a dummy function returning canned value of 1.

It seems to work. Before I try more complicated examples, I wanted to confirm if this is the right way to create .so?
I understand I'll have to modify my snapshot when kona upgrades and I need those upgrades.

thanks
Neeraj

Kevin Lawler

unread,
May 3, 2013, 12:49:20 AM5/3/13
to kona...@googlegroups.com
You should be able to use

https://github.com/kevinlawler/kona/blob/master/d.c.txt

renamed appropriately. That should be enough for simple cases. That is
what I used when I tested 2: dyadic. Depending on how many K calls you
want to use, that d.c.txt text file may need to be expanded,
potentially up to the size of or including the C API---I'm guessing; I
only got it working correctly, and my knowledge libraries and linking
is incomplete.

The source is at _2d. The line I used to compile shared libraries on
Mac OS X was

//Mac OS X: gcc -m64 -flat_namespace -undefined suppress
-dynamiclib file.c -o file.dylib

It's different---I think simpler---on other platforms. Updating the
source to include example comments for other platforms would be a good
exercise and helpful for other users.

Kevin
> --
> You received this message because you are subscribed to the Google Groups
> "Kona Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to kona-dev+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

per...@yahoo.com.hk

unread,
May 3, 2013, 1:13:11 PM5/3/13
to kona...@googlegroups.com
Hi, Kevin:
   I use the method you suggest by modify the d.c.txt to d.c  with change the function:
K h(K a,K b,K c,K d,K e,K f,K g,K h){return Ki(123);} to a more simple one 
K h(K a){return Ki(123);} to test the shared library function.

and compile under linux 64bit os, with :
  gcc -shared -fpic -o d.so d.c
    It compiles successfully. But When I loaded in k with:
  h:`d.so 2:(`h;1)  
   h[1]  
   It gets an error:
  /k: symbol lookup error: ./d.so: undefined symbol: Ki
   It seems that the function h in d.c cannot find the extern Ki(F); in k executable.
   Is there any suggestion for solving the problem or any example with compile and 
   link and run. Thanks a lot.
                           2013-05-04
                          perlawk.

Neeraj Rai於 2013年5月3日星期五UTC+8下午12時16分43秒寫道:

Neeraj Rai

unread,
May 3, 2013, 2:13:19 PM5/3/13
to kona...@googlegroups.com
Hi perlawk,

You can delete the extern lines from d.c and return K(123);
Ki calls newK which pulls in memory management functions.
Ldd -r d.so should tell you all the undefined symbols.

Kevin,
I got the simple program working. Avoiding newK calls for now to defer pulling in more code.
Perlawk post gives the linux linking functions that you may out in code comment at appropriate place.
But my input params are all messed up.
When i try with 2 parameters, 1st is junk and 2nd one has the value that 1stis one should have.
Thx
neeraj

Neeraj Rai

unread,
May 3, 2013, 8:11:57 PM5/3/13
to kona...@googlegroups.com
Hi Kevin,

I extended my simple example by linking with km.o to call newK and return list.
However, like the input param, the return values are also corrupted when printed on return.
I would need your inputs on 2 issues 
1. when you run your small test MAC, do you see the params passed correctly?
2. is it possible to upstream changes required to compile with km.o
   I copied the file 
   a)  removed some of the methods (expander, push, _n, etc)
    b) I compiled it with -fPIC (similar to what perlawk listed) - 
          this could be acheived by having another target like k_libk for which the tm.s.o is created with -fPIC option?
    c) instead of d.c.txt, I included ts.h and km.h
Please let me know your thoughts.
thx
Neeraj

Kevin Lawler

unread,
May 3, 2013, 10:02:29 PM5/3/13
to kona...@googlegroups.com
If you're getting corrupted values you're doing something wrong. I
would try getting the simple example correct in the way I suggested
previously. All you need is `d.c`. You should then be able to build
out from there. For example, if you want to use `newK` you can do that
by adding an `extern` signature to the header. You don't actually have
to know how `newK` works.

Kevin Lawler

unread,
May 3, 2013, 10:20:48 PM5/3/13
to kona...@googlegroups.com
OK, I tested it and I think something broke on the execution path for
functions loaded with 2:. Filed a ticket:
https://github.com/kevinlawler/kona/issues/186
Message has been deleted

per...@yahoo.com.hk

unread,
May 3, 2013, 11:30:42 PM5/3/13
to kona...@googlegroups.com
Hi, Kevin:
  The solution you suggest is even not passed the compiler:
in d.c:
    K h(K a){return K(123);}
compile with:
gcc -undefined_suppress -fpic -shared d.c -o d.so
d.c: In function ‘h’:
d.c:20:17: error: expected expression before ‘K’

per...@yahoo.com.hk

unread,
May 3, 2013, 11:34:58 PM5/3/13
to kona...@googlegroups.com


per...@yahoo.com.hk於 2013年5月4日星期六UTC+8上午11時30分42秒寫道:
Any suggestions:
   Thanks.

Neeraj Rai

unread,
May 3, 2013, 11:42:15 PM5/3/13
to kona...@googlegroups.com
ok, got it . I forgot my shared lib is running in k which already has newK - defining extern should suffice.
 
thanks
Neeraj

Kevin Lawler

unread,
May 3, 2013, 11:42:38 PM5/3/13
to kona...@googlegroups.com
I've verified two methods on OSX.

For `so` on OSX try

gcc -m64 -flat_namespace -undefined suppress -shared d.c -o shared.so

For `dylib` on OSX try

gcc -m64 -flat_namespace -undefined suppress -dynamiclib file.c -o
file.dylib

I haven't documented other systems.

Kevin Lawler

unread,
May 3, 2013, 11:45:53 PM5/3/13
to kona...@googlegroups.com
I expect the bug causing
https://github.com/kevinlawler/kona/issues/186 is a trivial oversight
and not a deep issue.

Neeraj Rai

unread,
May 3, 2013, 11:50:51 PM5/3/13
to kona...@googlegroups.com
Hi perlawk,

change "return K(123) " to return Ki(123)"
K is the typedef to struct k0* while Ki is a #define for int.
I was able to compile following program on centos 6:

gcc  -fPIC -shared myadd.c -o myadd.so
#include "d.c.txt"

K myadd (K x, K y)
{
  int a = kI(x);
  int b = kI(y);
  return Ki(123);
}

However, as Kevin noted, he has found some bug.
It is possible that my simple program works accidently and will start crashing some day.
the input param and return values are corrupted.

thanks
Neeraj

Neeraj Rai

unread,
May 4, 2013, 12:01:59 AM5/4/13
to kona...@googlegroups.com
Errata : Ki is a complex macros converting K to int.

per...@yahoo.com.hk

unread,
May 4, 2013, 7:15:29 AM5/4/13
to kona...@googlegroups.com

Hi Kevin and Neeraj:

As my last post, Ki symbol not found, It is because of a shared library don't
know where is the Ki even extern. The solution is compile the all k's c file
with gcc compiler option -rdynamic:
example:
  gcc -c -rdynamic kx.c
  gcc -o k kx.o *.o

After this, and use the short example in shared library d.so:
  K h(K, a) { return Ki(123);}

and in k interpreter:
  h : `d.so 2: `h,1
  h[0]  / return 123

But another problem come, with some argument:
 in shared library d.so:
  K f(Kx) { return Ki(kI(x)[0]);}

and in k interpreter:
  f : `d.so 2: `f,1
  f[3]  / return 0
        / expected return 3,

So there's something wrong with the kI(x)[0] structure.
Any suggestions?
  perlawk

Neeraj Rai

unread,
May 4, 2013, 9:51:08 AM5/4/13
to kona...@googlegroups.com
Hi Perlawk,

Compiling all source should not be needed. The required functions are in k executable and will be used by the .so code.

Let me list my steps and you can tell me which one fails for you with symbol not found.
1. create a myadd.c
-- contents :
#include "d.c.txt"
K myadd (K x, K y){  return Ki(123);}

2. build a shared lib:
gcc  -fPIC -shared myadd.c -o myadd.so

3. open a k shell
./k

4. register myadd from myadd.so as "a"
a:`"myadd.so" 2: (`myadd,2);

5. execute a with 2 params
a[2;3]
()

You last error is the issue Kevin opened. It seems something is broken there.
thanks
Neeraj

per...@yahoo.com.hk

unread,
May 4, 2013, 10:31:49 AM5/4/13
to kona...@googlegroups.com


Neeraj Rai於 2013年5月3日星期五UTC+8下午12時16分43秒寫道:

Hi, Neeraj:
The symbol not found error occurred at step 5:


5. execute a with 2 params
a[2;3]
./k: symbol lookup error: ./myadd.so: undefined symbol: Ki

 

per...@yahoo.com.hk

unread,
May 4, 2013, 10:48:55 AM5/4/13
to kona...@googlegroups.com


Neeraj Rai於 2013年5月3日星期五UTC+8下午12時16分43秒寫道:

Hi Neeraj:

If you try this example, you'll get what I mean:
>cat k.c
#include <stdio.h>
#include <dlfcn.h>

int Ki(int n) {
    return n;
}

int main(int argc, char **argv) {
    void *handle;
    int (*incr)(int);
    handle = dlopen ("d.so", RTLD_LAZY);
    incr = dlsym(handle, "incr");
    printf ("%d\n", (*incr)(2));
    dlclose(handle);
}

>cat d.c
extern int Ki(int);

int incr(int x) {
    return Ki(x) ;
}

gcc -fpic -shared -o d.so -d.c
gcc -o k k.c -ldl
./k
./k: symbol lookup error: ./d.so: undefined symbol: Ki


 
gcc -o k k.c -dl
./k
2

the k is similar to kona executable program, the d.so is the dy. lib.
symbol error is came from the shared library d.so cannot find symbol Ki in k's table, using the option -rdynamic
the d.so can find the symbol Ki. I search the internet to get the conclusion.
Thanks.


per...@yahoo.com.hk

unread,
May 4, 2013, 10:50:49 AM5/4/13
to kona...@googlegroups.com


Neeraj Rai於 2013年5月3日星期五UTC+8下午12時16分43秒寫道:

the last compile should be:
  gcc -o k k.c -rdynamic -ldl

Neeraj Rai

unread,
May 4, 2013, 1:05:21 PM5/4/13
to kona...@googlegroups.com
Hi Perlawk,

I can simulate your issue now.
Following the steps I listed above, my shared lib myadd.so was not being picked up ( figured out after adding print stmt)
I had to give the full path in step 4 - a:`"/tmp/myadd.so" 2: (`myadd,2);
Now I get symbol lookup error too.

Kevin , Is it possible to log an error if .so is not loaded ?
0.c linke 653:    P(e||!x,DOE)
doesn't seem to log error to screen.
Not sure if we need to open an issue for this ?

thanks
Neeraj


Neeraj Rai

unread,
May 4, 2013, 1:23:48 PM5/4/13
to kona...@googlegroups.com
Few more observations about shared lib loading:
1. when LD_LIBRARY_PATH doesn't contain ".". shared loading requires full path to be specified and doesn't assume current dir.
dlerror returns "cannot open shared object file: No such file or directory"

2. 0.c line 651 calls dlopen with RTLD_LAZY option which defers loading symbols at that time.
    The error is encountered only when function is called.
    Specifying RTLD_NOW would try to resolve the symbols when dlopen is called and catch errors early.
    What are the cons for using that options ?
  I changed the code locally and got an dlerror of "myadd.so: undefined symbol: Ki"

3. If it is determined that code for Ki needs to linked into the shared lib (myadd.so), I have extracted km.c and can share.

I would like to hear from more knowledgeable people on the issue.

thanks
Neeraj

Neeraj Rai

unread,
May 4, 2013, 8:26:18 PM5/4/13
to kona...@googlegroups.com
Hi Perlawk,

You are right - building k with -rdynamic option fixes the symbol not error:
Also, changing kx.c lines 425 to 433 a[ ==> kK(g)[  also fixes the parameter bug (awaiting confirmation from Kevin)

I added the following lines to the make:
k_dyn: CFLAGS += $(PRODFLAGS)
k_dyn: $(OBJS)
$(CC) ${CFLAGS} $^ -rdynamic -o $@ $(LDFLAGS)
then issue make k_dyn

1. create a myadd.c
-- contents :
#include "d.c.txt"
K myadd (K x, K y){  return Ki(123);}

2. build a shared lib:
gcc  -fPIC -shared myadd.c -o myadd.so

3. open a k_dyn shell
./k_dyn

4. register myadd from myadd.so as "a" (full path may be needed depending on LD_LIBRARY_PATH)
a:`"/tmpmyadd.so" 2: (`myadd,2);

5. execute a with 2 params
a[2;3]
5

Kevin Lawler

unread,
May 5, 2013, 12:07:47 AM5/5/13
to kona...@googlegroups.com
I'm having a hard time following this conversation. I think that

https://github.com/kevinlawler/kona/issues/186#issuecomment-17426627

is a solid demonstration that

1. The dlopen family calls work in C with the suggested compilation
parameters and includes (on OSX)
2. Kona crashes before the vf/dv family of functions can use the
dlopen family methods in K (on OSX)

this leads me to believe that something is messed up on the execution
path. If Kona is not crashing on 2 on other systems and working, that
would be interesting, though probably a lucky implementation dependent
effect.

>-rdynamic

Interesting. But do we need this? Maybe on other systems?

per...@yahoo.com.hk

unread,
May 5, 2013, 12:39:02 AM5/5/13
to kona...@googlegroups.com


Neeraj Rai於 2013年5月3日星期五UTC+8下午12時16分43秒寫道:

Neeraj:
    Cool job!
    How do u do that? Why?
  
    perlawk
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages