jruizgit / rules

Durable Rules Engine
MIT License
1.16k stars 205 forks source link

deleteRuleset fails and crash process #136

Open iddolazar opened 6 years ago

iddolazar commented 6 years ago

Hi, My goal is to be able to add new/updated rule to an existing ruleset.

I figured out that there is no such method in durableEngine and implemented a function similar to what is being done in testevents.js I keep my rulesets in memory cache so removing currently loaded ruleset and loading the updated version should do the trick.

I have added a function to the ruleset object as follow:

        that.updateRules = function(newRulesetDefinition, complete) {
            r.deleteRuleset(handle);
            for (var actionName in newRulesetDefinition) {
                var rule = newRulesetDefinition[actionName];
                if (typeof(rule.run) === 'string') {
                    actions[actionName] = promise(host.getAction(rule.run));
                } else if (typeof(rule.run) === 'function') {
                    actions[actionName] = promise(rule.run);
                } else if (rule.run.continueWith) {
                    actions[actionName] = rule.run.getRoot();
                }

                delete(rule.run);
            }

            handle = r.createRuleset(rulesetName, JSON.stringify(newRulesetDefinition), rulesetStateCacheSize);
            return true;
        };

(rulesetName & rulesetStateCacheSize - are saved within the constructor of the initial use) ** I am using host.registerRulesets to initially add the rules

when calling r.deleteRuleset(handle) my process is stopped with the following message:

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Any idea what I am doing wrong or different way to implement this?

Thanks as always! Iddo

jruizgit commented 6 years ago

Hi, thanks for posting the question. Would you be able to get a callstack for the crash?

iddolazar commented 6 years ago

Will be happy to send. How do i get such callstack? Is it written to any log i should copy from?

Menyadar commented 6 years ago

This is the same problem as in #96. Pretty old one. Each frontend (js/py/rb) binary module is just a thin wrapper around main code.

Function deleteRuleset is defined in

https://github.com/jruizgit/rules/blob/master/src/rules/rete.c#L1977

which in turn calls deleteBindingsList defined in

https://github.com/jruizgit/rules/blob/master/src/rules/net.c#L2471

Your handle is passed in directly. There are no safeguards, so passing invalid handle just tries to access whatever memory address it is evaluated to and generally SIGSEGVs the process.

import rules
rules.delete_ruleset(1)
read(3, "import rules\nrul", 16)        = 16
read(3, "es.delete_ruleset(1)\n\n", 4096) = 22
close(3)                                = 0
stat("prog.py", {st_mode=S_IFREG|0664, st_size=38, ...}) = 0
open("prog.py", O_RDONLY)               = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=38, ...}) = 0
ioctl(3, TCGETS, 0x7ffd7b8dfd50)        = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0664, st_size=38, ...}) = 0
read(3, "import rules\nrules.delete_rulese"..., 4096) = 38
lseek(3, 0, SEEK_SET)                   = 0
read(3, "import rules\nrules.delete_rulese"..., 4096) = 38
read(3, "", 4096)                       = 0
close(3)                                = 0
open("/tmp/rules/build/lib.linux-x86_64-2.7/rules.so", O_RDONLY|O_CLOEXEC) = 4
read(4, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000=\0\0\0\0\0\0"..., 832) = 832
fstat(4, {st_mode=S_IFREG|0775, st_size=654696, ...}) = 0
mmap(NULL, 2270840, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x7f28d59a6000
mprotect(0x7f28d59d0000, 2093056, PROT_NONE) = 0
mmap(0x7f28d5bcf000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x29000) = 0x7f28d5bcf000
close(4)                                = 0
mprotect(0x7f28d5bcf000, 4096, PROT_READ) = 0
mprotect(0x7f28d5bcf000, 4096, PROT_READ) = 0
close(3)                                = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x79} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

Avoid callign deleteRuleset and deleteClient until this is fixed or be 101% sure you have valid handle before calling any of these.

Menyadar commented 6 years ago
(gdb) bt
#0  deleteBindingsList (tree=tree@entry=0x1) at src/rules/net.c:2472
#1  0x00007ffff633d55c in deleteRuleset (handle=0x1) at src/rules/rete.c:1979
#2  0x00007ffff633614a in pyDeleteRuleset (self=<optimized out>, args=<optimized out>) at src/rulespy/rules.c:48
leoDreamer commented 5 years ago

Hi @iddolazar did your code work ? I try to run r.deleteRuleset(handle) in function ruleset (then file in durableEngine.js),get an error Could not start action, error code: 11 Error log:

Error: Could not start action, error code: 11
    at Object.that.dispatch (/Users/leo/Documents/S_Pro/rules/libjs/durableEngine.js:572:36)
    at Timeout.dispatchRules [as _onTimeout] (/Users/leo/Documents/S_Pro/rules/libjs/durableEngine.js:1299:23)
    at ontimeout (timers.js:505:15)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)

it be likely to the rule has been dispatched, has any solution?