Description From Bob Marinier 2008-06-13 11:30:52 (-) [reply]
The load-library command can "extend" the in-process SML kernel by loading
a
dll/so that can do things like register new RHS functions, or listen to
various
events (e.g., for logging purposes). The advantages of using a dll/so like
this is that it doesn't require the kernel or in-process client to be
modified,
and it doesn't require a remote connection (which is slow).
The problem is that it can only load C/C++ libraries. Many of our tools
(e.g.,
the Java debugger) are written in Java or other languages, so they cannot
benefit from this capability.
We had a discussion on the SML mailing list about how to go about providing
the
ability to do this for Java clients (the debugger in particular would
benefit
from this). That discussion is copied below (read starting at bottom).
--- start copy ----
Hey Doug,
Yes, I think we're on the same page now :) The disconnection issue
occurred to
me, too. Perhaps we could come up with a solution where we just unregister
for
all the callbacks and close the window (without explicitly shutting down or
disconnecting). Maybe it will even be possible to unload the library at
that
point. But if not, it probably won't be a big deal.
Bob
Douglas Pearson wrote:
> Bob,
>
> OK I think I get it now. We're not talking about debugger startup time,
we're talking about raw execution speed and maximizing that. I guess
having the kernel local to both the environment and the debugger is the
best possible case for connectivity.
>
> To test the threading I'd suggest having sml_InitLibrary() launch a new
C++ thread and have that call back independently into the kernel. That
should help to quickly flush out threading problems. You may find that you
need to put an extra mutex on the kernel side of the SML connection if
you've got two thread each calling into the local client interface at the
same time.
>
> As for wrapping up existing C++ objects in SWIG-style so they can be
handed to Java sounds like some of the stuff we had to do inside the old
"by hand" JNI code for event handlers and callbacks. I'm sure if you can
get the JVM loaded locally that code would point the way to doing the
wrapping up of the objects so they could be passed to Java. I wonder how
thread startup is handled if the JVM is embedded? I've never played with
that type of JVM.
>
> I'd guess some of the toughest areas would be around agent destruction
(since that was already complex threading between the document thread in
the debugger, kernel connectivity and the SWT UI thread) and what happens
if the user clicks the close button on the debugger window. There's no
existing model for disconnecting from a local connection to the kernel.
But maybe that's OK. If both are embedded I guess they all are expected to
come and go together.
>
> Doug
>
> On Thu, May 8, 2008 at 7:29 PM, Bob Marinier <rmarinie@umich.edu> wrote:
>
> To be clear, when I say "just work", I mean as if the kernel were
local to the debugger (so messages are passed directly, not via sockets).
If this can be made to work, it should be much faster to run the debugger
with an environment this way (at least if there's a trace being sent, which
there almost always is). Also note that this is independent of what
language the environment is written in (as the library loading occurs at
the SML level). As for stability, nothing would prevent us from running
the debugger separately like we do now if someone wants to do that.
>
> Bob
>
> Bob Marinier wrote:
>> Hey Doug,
>>
>> The way load-library works now, there aren't two clients. Rather,
there is one client, but it can be extended via code in an external dll/so.
load-library just passes a ClientSML Kernel object to the library's init
function, and then the library can do whatever it wants with it (e.g.,
register new event handlers, etc). With the debugger, the hope is that we
can give the debugger an existing ClientSML Kernel object and it will
register for events, etc., as it usually does (but with the kernel we give
it) and everything will "just work". That said, I have no idea what
possible interactions there might be with the threading.
>>
>> Bob
>>
>> Douglas Pearson wrote:
>>> OK Dave that makes sense if you're thinking of an embedded JVM like
in a browser. I've never explored a JVM running like that so I don't know
what issues it would raise.
>>>
>>> At the kernel level (ignoring Java etc. for now) I only ever
considered one client being in-process and accessing a given SML kernel
object. If the environment created the SML kernel object it could work if
it completely passed off ownership of that kernel to the JVM. If the idea
is to have both environment and debugger accessing the same kernel object
in-process I don't think that'll work. We could have the debugger treating
the kernel as a remote connection which just happens to be inside the same
process and maybe then you get better access speeds for the "remote"
messaging but it sounds like a lot of work for questionable gain. I'm not
sure why starting a JVM and debugger within the same process would be
faster than starting a separate process. The risk is you'd have the same
brittleness that applets suffer from where a crash in either environment or
debugger takes both down. Incidentally, this is why Sun is just now
releasing a new applet model where the JVM is in a separate process outside
of the browser.
>>>
>>> Is the root problem the startup time for the debugger? It seems
like maybe it would be better to include some sort of "auto-connect"
capability so you could launch your debugger (once per editing session) and
then have it automatically connect up to the environment each time that was
started. That would seem faster than anything based around launching a
debugger per environment restart. Also probably a lot easier (you'd just
need to have the debugger watch for a socket appearing on a specific port
and if it saw it, it would connect). But maybe I'm still not getting the
big picture here.
>>>
>>> Doug
>>>
>>> On Thu, May 8, 2008 at 6:11 PM, Bob Marinier <rmarinie@umich.edu>
wrote:
>>>
>>> Thanks for the clarifications, Dave. Even if SoarTech still
doesn't use
>>> the Java debugger, having this capability would be awesome (for
the
>>> ability to write loadable libraries in Java and for the massive
speed
>>> increase for same-machine debugging, which is pretty much 100%
of the
>>> use cases for us). Regarding SoarTech's usage, with this
ability, maybe
>>> it wouldn't be a big deal to automatically start up a Java
debugger with
>>> all of your environments (let people have two debuggers, at
least until
>>> they realize how useful the Java one is :)
>>>
>>> Bob
>>>
>>> Dave Ray wrote:
>>> > Hi Doug,
>>> >
>>> > The principle at work here is basically the same as a browser
with an
>>> > embedded JVM for applets. Here's how I think it might work:
>>> >
>>> > * Some environment (I don't think it technically has to be
C++) starts
>>> > up and creates a kernel.
>>> > * The environment (or the user) invokes "load-library
soardebugger..."
>>> > * This loads soardebugger.dll, a custom DLL provided with
SoarSuite
>>> > for this purpose and invokes its sml_InitLibrary function.
>>> > * sml_InitLibrary instantiates a new JVM and adds
SoarJavaDebugger.jar
>>> > and other required jars to the JVM's classpath
>>> > * Next, it looks up a secondary static entry point function
in the
>>> > debugger.Application class of the debugger. It would have a
signature
>>> > something like:
>>> > static void embeddedEntryPoint(Kernel kernel, String[]
args)
>>> > i.e. like a normal Java main() method with the kernel
provided
>>> > * From here the debugger starts up normally but uses the
passed in
>>> > kernel rather than creating a new one.
>>> >
>>> > Make sense? The parts that are probably tricky or show-
stoppers are:
>>> >
>>> > * Correctly wrapping the C++ Kernel* with the appropriate
SWIG wrapper
>>> > * Issues with the loading of SoarKernelSML.dll by both Java
and the
>>> > host environment. My guess is that since it's a DLL, it will
only get
>>> > loaded once and then reference counted so there shouldn't be
a problem
>>> > * Fighting between the two environments because the debugger
was
>>> > designed to do its thing on its own. I'm thinking especially
of
>>> > threading and the DocumentThread class here.
>>> > * Many other unforeseen difficulties
>>> >
>>> > That said, I think I should probably make sure I'm not
getting Bob's
>>> > hopes up too much with this as far as SoarTech usage goes. A
lot of
>>> > people at SoarTech are just used to the TSI and don't see any
major
>>> > compelling features that make the Java debugger much more
valuable,
>>> > especially when the TSI comes up by default, in process, in
all our
>>> > systems. So, though this may be a fun exercise, make sure you
have
>>> > good reasons other than SoarTech adoption before you take the
time to
>>> > do it :)
>>> >
>>> > Along those lines, here are two other thoughts... First,
leaving aside
>>> > the debugger, having a module that could do this for
arbitrary Java
>>> > SML clients would give you some nice interoperability when
for
>>> > whatever reason your main environment has to be in C++ (or
C#, or
>>> > anything not Java). You could basically do the same thing as
Bob's
>>> > doing with load-library, but implement the library in Java.
>>> >
>>> > Second, this week Jon or Bob mentioned a piece of code for
invoking
>>> > the debugger that's been copied and pasted all over the
place. It
>>> > would be cool if this was made into a real "debug" command in
CLI so
>>> > people can reuse it.
>>> >
>>> > Hope this helps,
>>> >
>>> > Dave
>>> >
>>> >
>>> > Douglas Pearson wrote:
>>> >> Not sure I'm quite clear on the in-process model. The JVM
for the
>>> >> debugger will want to run in its own process, so which
process owns
>>> >> the kernel object? The environment or the debugger? Or are
we only
>>> >> talking about Java environments in which case you could load
the
>>> >> debugger into that existing JVM. If it's a C++ environment
I don't
>>> >> see a way to share a kernel object with the debugger (just
because it
>>> >> seems like there's a process boundary here, never mind the
whole
>>> >> SWIG/JNI issue).
>>> >>
>>> >> I'm a bit muddled about the overall picture so need to get
that
>>> >> straight first before we dive into the tech.
>>> >>
>>> >> Doug
>>> >>
>>> >> On Thu, May 8, 2008 at 5:28 AM, Bob Marinier
<rmarinie@umich.edu
>>> >> <mailto:rmarinie@umich.edu>> wrote:
>>> >>
>>> >> In talking with Dave Ray at the workshop, it came up
that almost
>>> >> no one
>>> >> uses the Java debugger at SoarTech. We determined that
one of the
>>> >> primary reasons for this was that, unlike the TSI, it
couldn't be
>>> >> loaded
>>> >> in-process with an environment, and thus was slow (at
least by
>>> >> comparison to the in-process TSI).
>>> >>
>>> >> But perhaps we can fix that. A while ago Jon and I
created the
>>> >> load-library command, which can load a dll/so into the
environment's
>>> >> process. The library needs a function that looks like
this:
>>> >>
>>> >> char* sml_InitLibrary(Kernel* pKernel, int argc, char**
argv)
>>> >>
>>> >> So basically, we give the library a kernel, and it can
do
>>> >> whatever it
>>> >> wants (register for events, RHS functions, etc). The
limitation is
>>> >> that, on the surface, it looks like this only works with
C++.
>>> >>
>>> >> Dave Ray suggested that it should be possible to get
this to work
>>> >> with
>>> >> Java, though. The process would look something like
this:
>>> >>
>>> >> 1) Create a library with the above function.
>>> >> 2) Modify the debugger or the SWIG wrapper to add a
function that
>>> >> can
>>> >> take a kernel (e.g., so we can give it the one passed
into the
>>> >> library).
>>> >> 3) Have the init library function create a jvm, load the
>>> >> debugger, and
>>> >> pass the kernel object into the debugger for its use.
>>> >>
>>> >> Step 2 is the one I am the most fuzzy about (I don't
know how to
>>> >> do 1
>>> >> and 3 either, but I assume that's standard JNI stuff).
We
>>> >> already have
>>> >> a SWIG wrapper for the SML stuff, so perhaps we can
extend it
>>> >> somehow?
>>> >> This is actually the reverse problem that SWIG solves,
though, so we
>>> >> probably have to do something by hand.
>>> >>
>>> >> I suspect this is actually not very much code, so if we
knew what we
>>> >> were doing, we could probably have this done quickly.
Doug, do
>>> >> you have
>>> >> any experience with this sort of thing? Any insights or
tips you
>>> >> can
>>> >> give us?
>>> >>
>>> >> Thanks,
>>> >> Bob
Original issue reported on code.google.com by voigtjr@gmail.com on 23 Jul 2009 at 4:57
Original issue reported on code.google.com by
voigtjr@gmail.com
on 23 Jul 2009 at 4:57