opencog / atomspace

The OpenCog (hyper-)graph database and graph rewriting system
https://wiki.opencog.org/w/AtomSpace
Other
818 stars 232 forks source link

Expose opencog logger to Scheme #350

Closed ngeiswei closed 8 years ago

ngeiswei commented 9 years ago

Debugging Scheme functions is a pain, to this day I'm still not sure how to get the debug messages (from scheme code (display <message>)) out of a function like SchemeEval::eval_h.

It would be so much easier if one could invoke the OpenCog Logger directly from Scheme. Something like

(cog-logger-info "my info message")
(cog-logger-debug "my debug message")
(cog-logger-fine "my fine message")

etc.

I don't mind taking care of this, but some feedback might be welcome.

linas commented 9 years ago

I've got no opinion. Might be nice to start by adding a cog-logger-set-loglevel and got-logger-enable-stdout flags

ngeiswei commented 9 years ago

This is already a useful opinion.

ngeiswei commented 9 years ago

I've added code to support that + updated the wiki page http://wiki.opencog.org/wikihome/index.php/Scheme#Logger (rather brief but I want to move on).

ngeiswei commented 9 years ago

It's annoying, I can load the module from guile but I can't load it from a unit test (using load_scm_files_from_config), it says

ERROR: no code for module (opencog logger)

@linas, any idea?

ngeiswei commented 9 years ago

I mean, there's a scm file that contains

(use-modules (opencog logger))

that I'm loading with load_scm_files_from_config. The weird part is that it loads (use-modules (opencog exec)) without any problem. I don't understand what logger doesn't have that exec has...

ngeiswei commented 9 years ago

I tried running directly from the unit test

eval.eval("(use-modules (opencog logger))");

and I'm getting the same kind of error. That I do not get when running

eval.eval("(use-modules (opencog exec))");

I don't understand what exec has that logger hasn't...

linas commented 9 years ago

Its a bad error message: what is happening is that its not finding your library. You can work around this 3 different ways: 1) make install 2) call (setenv "LTDL_LIBRARY_PATH" "/path/to/your/build/dir") 3) put above into your~/.guile` file, which runs on startup

FWIW H ave this in my ~/.guile file:

 (use-modules (ice-9 readline))
  (activate-readline)
 (debug-enable 'backtrace)
; Record positions of source code expressions.
  (read-enable 'positions)
(add-to-load-path "/usr/local/share/opencog/scm")
(add-to-load-path ".")

although it is possible that the last two are hiding bugs that other people might see...

ngeiswei commented 9 years ago

Hi @linas , I don't think this has anything to do with .guile, because, as I said, I can load the module inside guile. But I cannot do so inside the unit test. I haven't understood yet what differentiate the guile environments between the guile interpreter and C++ SchemeEval.

ngeiswei commented 9 years ago

@linas I tried the above but as I expected they didn't fix the problem... I fear I'm gonna have to dig pretty deep into guiles internals...

ngeiswei commented 9 years ago

I managed to solve the problem by adding

eval.eval("(add-to-load-path \"/usr/local/share/opencog/scm\")");

in the unit test setup. However I still don't understand why exec doesn't need that...

linas commented 9 years ago

Nil,

don't confuse add-to-load-path which tells guile where to search for scheme modules, and DL_LIRARY_PATH which tells the glibc runtime loader where to look for shared libraries.

The problem is that when guile finds the scheme module, but that scheme module has a bug in it, then it will report an error. If the error is because the shared library can't be found, then the error message is very generic, and doesn't tell you to look at the shared lib.

Two reasons for a failing shared-lib:

1) it can't be found,

2) it is incorrectly linked, i.e. contains unresolved symbols. To check for unresolved symbols, use ldd -r aka ldd --function-relocs Well, it might be correctly linked, but some second shared lib can't be found ... etc.

ngeiswei commented 8 years ago

The solution seems to be to preload the module definition while setting up the unit test. As it is done with the other modules like exec and query. Here's an example

void TypeChoiceUTest::setUp(void)
{
    as->clear();
    config().set("SCM_PRELOAD",
                 "opencog/atomspace/core_types.scm, "
                 "opencog/scm/utilities.scm, "
                 "opencog/scm/opencog/query.scm, "
                 "opencog/scm/opencog/logger.scm");

    load_scm_files_from_config(*as);
}

then you can use the preloaded module definitions, like

(use-modules (opencog logger))

There's probably a better way but that works well so I'm closing.

linas commented 8 years ago

yeah, there are some remaining buglets to be straightened out. Sometimes, the SCM_PRELOAD seems not to be needed, but I'm too lazy to untangle whatever it is.