News : The level of daily SPAM has reached insane proportions, all registrations are now manual. I ask you to send me an e-mail (john (at) murga (dot) org), to confirm that you want me to create an account for you.


Post Reply  Post Thread 
Alien segfaults
Author Message
jpjacobs
Member
***


Posts: 113
Group: Registered
Joined: Jul 2007
Status: Offline
Reputation: 0
Post: #1
Alien segfaults

Hi!
I've been messing around with alien lately and I noticed that, if I use it (for loading the ncurses.so) it always segfaults on the end of the script, except when i do os.exit() explicitely. Is this a bug, or something to be expected for some reason?

BTW: another thing, I was wanting to write some CLI library (maybe based on ncurses if that turns out not to be too difficult) but does anyone have an idea of how to get only one character (or better, keypress) from stdin? I would like to use it so i can use keycommands, functionkeys, ... without having to wait for a following newline.

greetz,

Jan-Pieter

01-09-2009 01:41 AM
Find all posts by this user Quote this message in a reply
jpjacobs
Member
***


Posts: 113
Group: Registered
Joined: Jul 2007
Status: Offline
Reputation: 0
Post: #2
RE: Alien segfaults

Hi there!
I've got a more or less functional script put on the wiki snippets page...(http://www.murga-projects.com/wiki/index...e_Snippets look at the bottom; this works without segfaulting).

Now for the problems...
How do i get variables set by the library I use via alien?
Because ncurses uses a lot of variables that I need. Like for example the LINES and COLS of a screen. Apparently the get set by some function that has the same name as the vars, but when i try to use that it just segfaults.

Any Ideas?

Thx,

JP

01-09-2009 06:06 AM
Find all posts by this user Quote this message in a reply
Juergen
Member
***


Posts: 81
Group: Registered
Joined: May 2007
Status: Offline
Reputation: 0
Post: #3
RE: Alien segfaults

Actually it looks like it is not possible with alien to query external variables. While the basic functionality is there (alien just uses dlsym), alien lacks the functionality (or maybe I just overlooked it) to dereference the symbols, because it treats all symbols as functions.

Of course, there is always a special trick which could be used to circumvent such stupid limitations. In this case, it is possible to call dlsym directly.

This should demonstrate how it works.


Code:
if not (murgaLua_Version and tonumber(murgaLua_Version) >= 68) then
   require"luarocks.require"
   require"alien"
end

curses=alien.load("/usr/lib/libncurses.so")
getsym=alien.default.dlsym
getsym:types("pointer","pointer","string")
curses.initscr:types("pointer")
curses.endwin:types("int")
curses.initscr()
colons=getsym(nil,"COLS")
lines=getsym(nil,"LINES")
curses.endwin()
print("The terminal has "..alien.toint(colons).." cols and "..alien.toint(lines).." lines")
os.exit()


It is really easy. Since alien uses "RTLD_GLOBAL" to load the library, it is possible to query symbols with dlsym. It isn't even necessary to load libdl.so, since alien already uses it. This works of course only on systems that have "libdl.so" support.

Juergen

01-10-2009 10:36 AM
Find all posts by this user Quote this message in a reply
jpjacobs
Member
***


Posts: 113
Group: Registered
Joined: Jul 2007
Status: Offline
Reputation: 0
Post: #4
RE: Alien segfaults

That is just awesome... thanks!
As I know barely anything about shared libs, I was kinda in the dark.
Thanks!

01-10-2009 10:06 PM
Find all posts by this user Quote this message in a reply
Juergen
Member
***


Posts: 81
Group: Registered
Joined: May 2007
Status: Offline
Reputation: 0
Post: #5
RE: Alien segfaults

I totally fogot to say, that "getsym(nil,"COLS")" and "getsym(nil,"LINES")" are two expensive operations and you have to use them only once. They are only necessary to get the memory location (pointer) where the "COLS" and "LINES" values are stored. The location in memory does not change. So it would make more sense to put those lines on top after the alien.load("libncurses.so"):

Code:
getsym=alien.default.dlsym -- give it a shorter name
getsym:types("pointer","pointer","string")
-- dlsym searches for the symbol name given as second parameter.
-- The first parameter is a pointer to the location where the library has been loaded.
-- dlsym returns a pointer to the symbol.
curses=alien.load("libncurses.so")
colons=getsym(nil,"COLS")  
-- We have no pointer to the ncurses library.
-- Unfortunately there is no way to get that information from alien. But it doesn't matter,
-- the linker can find it nevertheless, because alien did load it with the global option enabled.
-- Therfore it is enough to us a NULL pointer (you have to use nil in lua, 0 won't do it).
lines=getsym(nil,"LINES")
curses.initscr:types("pointer")
curses.endwin:types("int")

curses.initscr()
curses.endwin()
-- ncurses has to be called to fill the variables with meaningfull values.

print("The terminal has "..alien.toint(colons).." cols and "..alien.toint(lines).." lines")
-- Since we have the pointers to the global variables/memory locations (wrapped in Lua userdata),
-- we can dereference it any time we want.
os.exit()


Juergen

01-11-2009 03:05 AM
Find all posts by this user Quote this message in a reply
jpjacobs
Member
***


Posts: 113
Group: Registered
Joined: Jul 2007
Status: Offline
Reputation: 0
Post: #6
RE: Alien segfaults

uhu indeed nice to know...
Now I've gotten a little further on in the ncurses intro, I noticed they recommend using getmaxx(scr) and getmaxy(scr) instead of directly accessing LINES and COLS.
With your example, I also saw the initscr() should return a pointer to the stdscr, which i did not know. Aparently when you call getmax.() without argument, it returns some insane number like 2078x1050...
But I'll need it anyway as it seems that there are sooooo much magic variables in ncurses.
Thx again.
Jan-Pieter

01-11-2009 04:40 AM
Find all posts by this user Quote this message in a reply
Post Reply  Post Thread 

View a Printable Version
Send this Thread to a Friend
Subscribe to this Thread | Add Thread to Favorites

Forum Jump: