How does a plugin unload itself?

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
May 30, 2008
122
1
#1
If I have a plugin which has encountered a fatal error, is there a way
I can unload it? UnloadOnePlugin() with your own name doesn't seem
good - it crashed my session.

I'm thinking of a plugin which has, as a result of a serious error,
corrupted its internal state. The plugin itself is unusable, but the
main TCC session is fine. So I'd like the plugin to cleanly unload
itself to protect the main session from crashes.

Thanks,
Paul.
 
#2
InitializePlugin() can return non-zero if you know then that the plugin
shouldn't be loaded.

Later you could use Plugin_Cmd() or UnloadOnePlugin() (TakeCmd.h). But really,
you should avoid the plugin becoming unusable.

On Fri, 18 Jul 2008 16:00:57 -0500, "p.f.moore" <> wrote:


>If I have a plugin which has encountered a fatal error, is there a way
>I can unload it? UnloadOnePlugin() with your own name doesn't seem
>good - it crashed my session.
>
>I'm thinking of a plugin which has, as a result of a serious error,
>corrupted its internal state. The plugin itself is unusable, but the
>main TCC session is fine. So I'd like the plugin to cleanly unload
>itself to protect the main session from crashes.
 
May 30, 2008
122
1
#3
2008/7/18 vefatica <>:

> InitializePlugin() can return non-zero if you know then that the plugin
> shouldn't be loaded.
No, it's later, when retained state in the plugin has somehow got corrupted.


> Later you could use Plugin_Cmd() or UnloadOnePlugin() (TakeCmd.h). But really,
> you should avoid the plugin becoming unusable.
UnloadOnePlugin doesn't seem to work (my experimental code crashed).
Not surprising, after all you're trying to unload the plugin
containing the currently running code... I suspect that Plugin_Cmd
would be similar.

The problem I'm trying to address is a fatal runtime error in the Lua
runtime I'm hosting - my plugin protects against any corruption even
in pretty terminal circumstances (the most obvious being out of
memory). My code stays in control, but the dead interpreter runtime
could be in a pretty sorry state. It's not even clear to me that it
can be safely cleaned up (I'm attempting to establish the precise
situation here). But the safest thing would be to tear down the whole
plugin. (The alternative would be to either shut down TCC, which I'm
trying to avoid at all costs, or to leave things in a state where a
new call into the plugin could hit corrupt data and crash TCC, which
again I want to avoid).

Ultimately, the fatal errors I'm protecting against are so rare that
maybe I just shouldn't bother. But I'm trying to be seriously
defensive here.

Paul.
 
May 30, 2008
42
0
#5
From: p.f.moore
Sent: Friday, July 18, 2008 6:08 PM
Subject: RE: [Plugins-t-331] How does a plugin unload itself?

> > Later you could use Plugin_Cmd() or UnloadOnePlugin() (TakeCmd.h). But
really,

> > you should avoid the plugin becoming unusable.
>
> UnloadOnePlugin doesn't seem to work (my experimental code crashed).
> Not surprising, after all you're trying to unload the plugin
> containing the currently running code... I suspect that Plugin_Cmd
> would be similar.
As loaded DLLs are reference-counted, you might be able to achieve what you
want by calling LoadLibrary on yourself before telling TCC to unload the
plugin. In theory, the plugin should remain in memory even after TCC makes
its FreeLibrary call and then all you have to do is figure out how to leave
as little as possible behind. Obviously you can't just FreeLibrary yourself
before returning, as that will trigger the same problem. One approach that
might work would be to take the buffer TCC gives the plugin to work with,
VirtualProtect it to allow execution, make sure it's null-terminated with
enough room to put the cleanup code *after* the null terminator, and then
call into that.

Anyway, I'm sure it's far more effort than it's worth. It's more just at an
academic level -- it *is* possible :-)

However, unloading the plugin isn't going to fix anything that corrupt code
has broken. The only real way to fix memory corruption within the process is
to tear it down and make a new one.

Jonathan Gilbert
 
May 30, 2008
122
1
#6
2008/7/19 logic <>:

> However, unloading the plugin isn't going to fix anything that corrupt code
> has broken. The only real way to fix memory corruption within the process is
> to tear it down and make a new one.
Absolutely. I also agree with your point that it's more trouble than
it's worth. All I really want to do is to get back to the command
prompt in a way that tells the user that the plugin's state is
trashed, and they should save their work. Tidying up as best I can
before I get out simply reduces the risk of anything else being broken
as the user tidies up.

I've had confirmation from the Lua list that a clean tidy-up of the
Lua interpreter is possible, so writing an error suggesting unloading
the plugin, then cleaning down the interpreter should be fine. (Lua is
robust enough that nothing outside the interpreter state will be
affected).

Thanks,
Paul.
 
#7
I suppose you'll discover the need to unload the plugin during the execution of a user command which causes the calling of some function in the plugin. If that's so, then the plugin can cause itself to be unloaded when that user command returns by calling a function like the one below. It's rather sneaky, but it works (tested). When the in-progress user command finishes, the new POST_EXEC alias is called. The new POST_EXEC alias unloads the plugin and restores the old POST_EXEC alias. I suppose this could also **reload** the plugin.


VOID UnloadMe ( VOID )
{
WCHAR szAliasArgs[4096], *pszOldPostExec = GetAlias(L"POST_EXEC");
Sprintf(szAliasArgs,
L"POST_EXEC=PLUGIN /U %s & ALIAS POST_EXEC=%s", pluginfo.pszDll, pszOldPostExec);
Alias_Cmd(szAliasArgs);
}
 
May 30, 2008
122
1
#8
2008/7/19 vefatica <>:

> I suppose you'll discover the need to unload the plugin during the execution of a user command which causes the calling of some function in the plugin. If that's so, then the plugin can cause itself to be unloaded when that user command returns by calling a function like the one below. It's rather sneaky, but it works (tested). When the in-progress user command finishes, the new POST_EXEC alias is called. The new POST_EXEC alias unloads the plugin and restores the old POST_EXEC alias. I suppose this could also **reload** the plugin.
>
>
> VOID UnloadMe ( VOID )
> {
> WCHAR szAliasArgs[4096], *pszOldPostExec = GetAlias(L"POST_EXEC");
> Sprintf(szAliasArgs,
> L"POST_EXEC=PLUGIN /U %s & ALIAS POST_EXEC=%s", pluginfo.pszDll, pszOldPostExec);
> Alias_Cmd(szAliasArgs);
> }
Sneaky! I like it :-)

One thought - does it work in the face of special characters and
quoting in the original POST_EXEC? For example

ALIAS POST_EXEC=`echo hello & echo there`

Paul.
 
#9
On Sat, 19 Jul 2008 17:25:47 -0500, "p.f.moore" <> wrote:


>> VOID UnloadMe ( VOID )
>> {
>> WCHAR szAliasArgs[4096], *pszOldPostExec = GetAlias(L"POST_EXEC");
>> Sprintf(szAliasArgs,
>> L"POST_EXEC=PLUGIN /U %s & ALIAS POST_EXEC=%s", pluginfo.pszDll, pszOldPostExec);
>> Alias_Cmd(szAliasArgs);
>> }
>---End Quote---
>Sneaky! I like it :-)
>
>One thought - does it work in the face of special characters and
>quoting in the original POST_EXEC? For example
>
> ALIAS POST_EXEC=`echo hello & echo there`
I didn't try it but my guess is "yes". I imaging that calling Alias_Cmd()
directly bypasses command line parsing (like ALIAS /R?). The unquoted ampersand
certainly works since it's used by the routine above. If you use ALIAS at the
command line, the protecting back-quotes are gone by the time Alias_Cmd() gets a
look at its args.
 

samintz

Scott Mintz
May 20, 2008
1,204
11
Solon, OH, USA
#10
I was going to suggest using the DEFER command. I don't know if that
would work or not as the docs say it is intended to be used inside a batch
file.

-Scott

vefatica <> wrote on 07/19/2008 08:01:17 PM:


> On Sat, 19 Jul 2008 17:25:47 -0500, "p.f.moore" <> wrote:
>

> Quote:
>
> >Sneaky! I like it :-)
> >
> >One thought - does it work in the face of special characters and
> >quoting in the original POST_EXEC? For example
> >
> > ALIAS POST_EXEC=`echo hello & echo there`
>
> I didn't try it but my guess is "yes". I imaging that calling
Alias_Cmd()

> directly bypasses command line parsing (like ALIAS /R?). The
> unquoted ampersand
> certainly works since it's used by the routine above. If you use ALIAS
at the

> command line, the protecting back-quotes are gone by the time
> Alias_Cmd() gets a
> look at its args.
>
>