在计算NeqFunction时,是什么导致剪辑6.3中出现此分段错误



TL/DR:

我在一个大型机器人框架中使用clips 6.3遇到分段故障,如果有任何可能导致这些故障的提示,我将不胜感激(例如,这是已知的并在新版本中修复的,还是存在可能导致这些类型的分段故障的已知错误),或者我如何在回溯中将故障值追溯到其根源。

引言

你好,

多年来,我一直在fawkes框架中的机器人应用程序中使用剪辑。最近,在执行过程中,我在一些功能分支中遇到了分割错误。经过数周的寻找,我对如何继续下去失去了任何想法,需要帮助来追踪原因。

系统和软件

Fedora 35(尽管在Fedora 33和Fedora 34上也观察到segfault)

剪辑版本:6.3(来自fedora包来源)通过夹子嵌入fawkes框架内mm。尽管该框架是多线程的,但我不认为分割错误是由运行剪辑环境的线程以外的其他线程引起的。主要是因为segfault只发生在一些功能分支中,这些分支只更改clips代码,而没有这些代码,所以多年来一切都是稳定的。尽管如此,我认为重要的是要提到一些线程问题导致这些崩溃的轻微可能性。。。

背景战术

#0  0x00007f3354394b1e in PropagateReturnAtom (value=0x25, type=0, theEnv=0x7f339c6e0970) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:784
#1  PropagateReturnValue (theEnv=theEnv@entry=0x7f339c6e0970, vPtr=vPtr@entry=0x7f333e7fafa0) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:750                                                                
#2  0x00007f335439aeb2 in EvaluateExpression (theEnv=0x7f339c6e0970, problem=<optimized out>, returnValue=0x7f333e7fafa0) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:432
#3  0x00007f335436a839 in NeqFunction (theEnv=0x7f339c6e0970) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/prdctfun.c:167
#4  0x00007f335439b3a3 in EvaluateExpression (theEnv=0x7f339c6e0970, problem=0x7f33380e3c80, returnValue=0x7f333e7fb0a0) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:180
#5  0x00007f335436158a in EvaluateJoinExpression (theEnv=theEnv@entry=0x7f339c6e0970, joinExpr=0x7f33380e3c80, joinPtr=joinPtr@entry=0x7f33380e3b20) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/drive.c:629            
#6  0x00007f3354361aef in NetworkAssertRight (join=0x7f33380e3b20, rhsBinds=0x7f333996fe10, theEnv=0x7f339c6e0970) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/drive.c:235
#7  NetworkAssertRight (theEnv=0x7f339c6e0970, rhsBinds=0x7f333996fe10, join=0x7f33380e3b20) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/drive.c:112                                                                    
#8  0x00007f335433b14e in ProcessFactAlphaMatch (theEnv=theEnv@entry=0x7f339c6e0970, theFact=0x7f333a05b2c0, theMarks=<optimized out>, thePattern=thePattern@entry=0x7f33380e3ab0)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmch.c:552                                    
#9  0x00007f3354340fd1 in ProcessMultifieldNode (theEnv=theEnv@entry=0x7f339c6e0970, thePattern=<optimized out>, thePattern@entry=0x7f33380e3ab0, markers=<optimized out>,
markers@entry=0x7f3339cd4d10, endMark=endMark@entry=0x7f3339cd4d10, offset=5) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmch.c:367
#10 0x00007f3354341204 in FactPatternMatch (theEnv=theEnv@entry=0x7f339c6e0970, theFact=0x7f333a05b2c0, patternPtr=0x7f33380e3ab0, offset=offset@entry=5, markers=0x7f3339cd4d10, endMark=endMark@entry=0x7f3339cd4d10)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmch.c:243                                    
#11 0x00007f3354340d8c in ProcessMultifieldNode (theEnv=theEnv@entry=0x7f339c6e0970, thePattern=thePattern@entry=0x7f33380e2c30, markers=<optimized out>, markers@entry=0x0, endMark=endMark@entry=0x0, offset=0)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmch.c:420                                    
#12 0x00007f3354341204 in FactPatternMatch (theEnv=theEnv@entry=0x7f339c6e0970, theFact=theFact@entry=0x7f333a05b2c0, patternPtr=0x7f33380e2c30, offset=offset@entry=0, markers=markers@entry=0x0, endMark=endMark@entry=0x0)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmch.c:243                                    
#13 0x00007f3354343531 in EnvAssert (theEnv=0x7f339c6e0970, vTheFact=0x7f333a05b2c0) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmngr.c:770
#14 0x00007f335431c08f in AssertCommand (theEnv=0x7f339c6e0970, rv=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factcom.c:235
#15 0x00007f335439b138 in EvaluateExpression (theEnv=0x7f339c6e0970, problem=0x7f33380dd0d0, returnValue=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:349                                     
#16 0x00007f335435f993 in PrognFunction (theEnv=0x7f339c6e0970, returnValue=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/prcdrfun.c:570
#17 0x00007f335439b138 in EvaluateExpression (theEnv=0x7f339c6e0970, problem=0x7f33380dd090, returnValue=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:349                                     
#18 0x00007f33543589ce in EvaluateProcActions (theEnv=0x7f339c6e0970, theModule=<optimized out>, actions=0x7f33380dd090, lvarcnt=0, result=0x7f333e7fb920, crtproc=0x7f335433aa90 <UnboundDeffunctionErr>)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/prccode.c:873                                    
#19 0x00007f3354340239 in CallDeffunction (theEnv=0x7f339c6e0970, dptr=0x7f33380dcff0, args=0x7f333e7fb6b0, result=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/dffnxexe.c:131                           
#20 0x00007f33543490ea in EvaluateDeffunctionCall (theEnv=0x7f339c6e0970, value=<optimized out>, result=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/dffnxfun.c:661
#21 0x00007f335439af67 in EvaluateExpression (theEnv=0x7f339c6e0970, problem=0x7f33380e2800, returnValue=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:422 
#22 0x00007f335435f993 in PrognFunction (theEnv=0x7f339c6e0970, returnValue=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/prcdrfun.c:570
#23 0x00007f335439b138 in EvaluateExpression (theEnv=0x7f339c6e0970, problem=0x7f33380e2760, returnValue=0x7f333e7fb920) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/evaluatn.c:349
#24 0x00007f33543589ce in EvaluateProcActions (theEnv=0x7f339c6e0970, theModule=<optimized out>, actions=0x7f33380e2760, lvarcnt=0, result=0x7f333e7fb920, crtproc=0x0)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/prccode.c:873                                    
#25 0x00007f33543915ad in EnvRun (theEnv=0x7f339c6e0970, runLimit=-1) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/engine.c:315
#26 0x00007f3354432e94 in CLIPS::Environment::run(long) (this=0x7f339c64bf00, runlimit=runlimit@entry=-1) at /usr/src/debug/clipsmm-0.3.5-11.fc35.x86_64/clipsmm/environment.cpp:134                                                          
#27 0x00007f33540091b7 in ClipsExecutiveThread::loop() (this=0x7f339c71a5d0) at /home/tarikwork/fawkes-robotino/fawkes/src/libs/core/utils/lockptr.h:301
#28 0x00007f33adaa6d6c in fawkes::Thread::run() (this=0x7f339c71a5d0) at /home/tarikwork/fawkes-robotino/fawkes/src/libs/core/threading/thread.cpp:947
#29 0x00007f33adaa791a in fawkes::Thread::entry(void*) (pthis=0x7f339c71a5d0) at /home/tarikwork/fawkes-robotino/fawkes/src/libs/core/threading/thread.cpp:565
#30 0x00007f33ad6e1da2 in start_thread (arg=<optimized out>) at pthread_create.c:443                                   
#31 0x00007f33ad6819e0 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81     

剪辑的相关规则(我认为)

这是我调试日志中的最后一个条目:

D 16:45:38.408820 CLIPS (executive): FIRE  131 central-run-parallel-goal-commit: f-39749,f-39728                      
D 16:45:38.408838 CLIPS (executive): <== f-39749 (goal (id CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839) (class PAYMENT-GOALS) (type ACHIEVE) (sub-type CENTRAL-RUN-SUBGOALS-IN-PARALLEL) (parent CENTRAL-RUN-PARALLEL-PRODUCE-ORDER-gen1840) (mode EXPANDED) (outcome UNKNOWN) (warning) (error) (message "") (priority 50) (params) (meta) (meta-fact 0) (meta-template nil) (required-resources) (acquired-resources) (committed-to nil) (verbosity DEFAULT) (is-executable TRUE))
D 16:45:38.408864 CLIPS (executive): ==> f-39778 (goal (id CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839) (class PAYMENT-GOALS) (type ACHIEVE) (sub-type CENTRAL-RUN-SUBGOALS-IN-PARALLEL) (parent CENTRAL-RUN-PARALLEL-PRODUCE-ORDER-gen1840) (mode COMMITTED) (outcome UNKNOWN) (warning) (error) (message "") (priority 50) (params) (meta) (meta-fact 0) (meta-template nil) (required-resources) (acquired-resources) (committed-to nil) (verbosity DEFAULT) (is-executable TRUE))        
D 16:45:38.408911 CLIPS (executive): FIRE  132 wm-sync-update-goals-on-mode-change: f-39778,f-16227,f-39775,f-39774
D 16:45:38.408924 CLIPS (executive): <== f-39775 (wm-fact (id "/template/fact/goal?id=CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839") (key template fact goal args? id CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839) (type SYMBOL) (is-list TRUE) (value nil) (values class PAYMENT-GOALS type ACHIEVE sub-type CENTRAL-RUN-SUBGOALS-IN-PARALLEL parent CENTRAL-RUN-PARALLEL-PRODUCE-ORDER-gen1840 mode EXPANDED outcome UNKNOWN warning [ ] error [ ] message "" priority 50 params [ ] meta [ ] meta-template nil required-resources [ ] acquired-resources [ ] committed-to nil verbosity DEFAULT is-executable TRUE))
D 16:45:38.408936 CLIPS (executive): <== f-39774 (wm-fact (id "/template/fact/goal-meta?goal-id=CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839") (key template fact goal-meta args? goal-id CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839) (type SYMBOL) (is-list TRUE) (value nil) (values assigned-to nil restricted-to nil order-id nil ring-nr nil root-for-order nil run-all-ordering 1))                                                             
D 16:45:38.409030 CLIPS (executive): ==> f-39779 (wm-fact (id "") (key template fact goal args? id CENTRAL-RUN-PARALLEL-PAYMENT-GOALS-gen1839) (type SYMBOL) (is-list TRUE) (value nil) (values class PAYMENT-GOALS type ACHIEVE sub-type CENTRAL-RUN-SUBGOALS-IN-PARALLEL parent CENTRAL-RUN-PARALLEL-PRODUCE-ORDER-gen1840 mode COMMITTED outcome UNKNOWN warning [ ] error [ ] message "" priority 50 params [ ] meta [ ] meta-template nil required-resources [ ] acquired-resources [ ] committed-to nil verbosity DEFAULT is-executable TRUE))

最后激发的规则如下:

(deffunction assert-template-wm-fact (?fact-id ?id-slots ?other-slots)          
" Helper to create a wm-fact from a template fact"                                                                     
(assert (wm-fact (key template fact (fact-relation ?fact-id)                                                         
args? (template-fact-slots-to-key-vals ?fact-id ?id-slots))                                        
(type SYMBOL)                                                                                       
(is-list TRUE)                                                                                      
(values (template-fact-slots-to-key-vals ?fact-id ?other-slots)))                                   
)                                                                                                                    
)         
(defrule wm-sync-update-goals-on-mode-change                                                                           
?g <- (goal (id ?id) (mode ?mode))                                                                                   
?gm <- (goal-meta (goal-id ?id))                                                                                     
?wm <- (wm-fact (key template fact goal args? id ?id)                                                                
(values $? mode ?other-mode&:(neq ?mode ?other-mode) $?))                                            
?wm2 <- (wm-fact (key template fact goal-meta args? goal-id ?id))                                                    
=>                                                                                                                   
(retract ?wm)                                                                 
(retract ?wm2)                                                                                                       
(assert-template-wm-fact ?g                                                                                          
?*GOAL_ID_SLOTS*                                                                            
(delete-member$ (deftemplate-remaining-slots goal ?*GOAL_ID_SLOTS*)                         
meta-fact))                                                             
(assert-template-wm-fact ?gm                                                                                         
?*GOAL_META_ID_SLOTS*                                                                       
(deftemplate-remaining-slots goal-meta ?*GOAL_META_ID_SLOTS*))                              
)

我的回溯进度

第31-13帧基本上描述了直到日志中的执行,在日志中,上面的规则断言了第一个新的wm-fact,然后剪辑的魔力发生了,我试图向自己解释如下(从阅读维基百科上关于rete算法的文章和查看剪辑6.3的源代码开始):

从本质上讲,现在需要在Rete网络中评估新事实,以了解所有现有规则激活如何受到新事实的影响。在帧11-12中,完成了这些检查中的一个,但没有用,在帧10中,找到了与现有模式的匹配(因为我认为帧9-7本质上意味着建立了匹配,现在需要进一步评估)。因此,我试图查看第10帧:

第10帧

(gdb) frame 10                                                                  
#10 0x00007f3354341204 in FactPatternMatch (theEnv=theEnv@entry=0x7f339c6e0970, theFact=0x7f333a05b2c0, patternPtr=0x7f33380e3ab0 , offset=offset@entry=5, markers=0x7f3339cd4d10, endMark=endMark@entry=0x7f3339cd4d10)
at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/factmch.c:243
243!           { ProcessMultifieldNode(theEnv,patternPtr,markers,endMark,0); }
// look at the content of patternPtr=0x7f33380e3ab0  
(gdb) p (factPatternNode) *0x7f33380e3ab0                                       
$62 = {header = {firstHash = 0x7f3339018780, lastHash = 0x7f33399c8ac0, entryJoin = 0x7f33380e3b20, rightHash = 0x7f3338099a30, singlefieldNode = 0, multifieldNode = 1, stopNode = 1, initialize = 0, marked = 0, beginSlot = 0,
endSlot = 1, selector = 0}, bsaveID = 0, whichField = 4, whichSlot = 5, leaveFields = 0, networkTest = 0x0, nextLevel = 0x0, lastLevel = 0x7f33380e3a10, leftNode = 0x0, rightNode = 0x0}
// look at the content of entryJoin = 0x7f33380e3b20 and follow the join links
(gdb) p (joinNode) *0x7f33380e3b20                                              
$63 = {firstJoin = 0, logicalJoin = 0, joinFromTheRight = 0, patternIsNegated = 0, patternIsExists = 0, initialize = 0, marked = 0, rhsType = 1, depth = 3, bsaveID = 0, memoryAdds = 4299, memoryDeletes = 4167, memoryCompares = 5006,
leftMemory = 0x7f33380b3d60, rightMemory = 0x0, networkTest = 0x7f33380e3c40, secondaryNetworkTest = 0x0, leftHash = 0x7f339c7f3b40, rightHash = 0x0, rightSideEntryStructure = 0x7f33380e3ab0, nextLinks = 0x7f33380b4ba0,
lastLevel = 0x7f33380e29d0, rightMatchNode = 0x0, ruleToActivate = 0x0}       
(gdb) p (joinLink) *0x7f33380b4ba0                                              
$64 = {enterDirection = 0 '00', join = 0x7f33380e3cf0, next = 0x0, bsaveID = 0}
(gdb) p (joinNode) *0x7f33380e3cf0                                              
$65 = {firstJoin = 0, logicalJoin = 0, joinFromTheRight = 0, patternIsNegated = 0, patternIsExists = 0, initialize = 0, marked = 0, rhsType = 1, depth = 4, bsaveID = 0, memoryAdds = 0, memoryDeletes = 0, memoryCompares = 0,
leftMemory = 0x7f33380b4bd0, rightMemory = 0x0, networkTest = 0x7f33380b92e0, secondaryNetworkTest = 0x0, leftHash = 0x7f33380b4990, rightHash = 0x0, rightSideEntryStructure = 0x7f33380e3210, nextLinks = 0x7f33380b47e0,
lastLevel = 0x7f33380e3b20, rightMatchNode = 0x7f33380e32b0, ruleToActivate = 0x0}
(gdb) p (joinLink) *0x7f33380b47e0                                              
$66 = {enterDirection = 0 '00', join = 0x7f33380e3e10, next = 0x0, bsaveID = 0}
(gdb) p (joinNode) *0x7f33380e3e10                                              
$67 = {firstJoin = 0, logicalJoin = 0, joinFromTheRight = 0, patternIsNegated = 0, patternIsExists = 0, initialize = 0, marked = 0, rhsType = 0, depth = 5, bsaveID = 0, memoryAdds = 0, memoryDeletes = 0, memoryCompares = 0,
leftMemory = 0x7f33380b72a0, rightMemory = 0x0, networkTest = 0x0, secondaryNetworkTest = 0x0, leftHash = 0x0, rightHash = 0x0, rightSideEntryStructure = 0x0, nextLinks = 0x0, lastLevel = 0x7f33380e3cf0, rightMatchNode = 0x0,
ruleToActivate = 0x7f33380e3ec0}
// We are at the end, this should be the rule which is checked for activation?!                                              
(gdb) print (defrule) *0x7f33380e3ec0                                           
$68 = {header = {name = 0x7f33380b6e50,                                         
ppForm = 0x7f33380e3f30 "(defrule MAIN::wm-sync-update-goals-on-parent-changen   ?g <- (goal (id ?id) (parent ?parent))n   ?gm <- (goal-meta (goal-id ?id))n   ?wm <- (wm-fact (key template fact goal args? id ?id) (values $? p"..., whichModule = 0x7f339c7d22d0, bsaveID = 0, next = 0x7f33380e4570, usrData = 0x0}, salience = 0, localVarCnt = 0, complexity = 19, afterBreakpoint = 0, watchActivation = 0, watchFiring = 1, autoFocus = 0, executing = 0,
dynamicSalience = 0x0, actions = 0x7f33380e37a0, logicalJoin = 0x0, lastJoin = 0x7f33380e3e10, disjunct = 0x0}

根据我的理解,有问题的规则被称为wm-sync-update-goals-on-parent-change,如下所示:

(defrule wm-sync-update-goals-on-parent-change                                  
?g <- (goal (id ?id) (parent ?parent))                                        
?gm <- (goal-meta (goal-id ?id))                                              
?wm <- (wm-fact (key template fact goal args? id ?id)                         
(values $? parent ?other-parent&:(neq ?parent ?other-parent) $?))
?wm2 <- (wm-fact (key template fact goal-meta args? goal-id ?id))             
=>                                                                            
(retract ?wm)                                                                 
(retract ?wm2)                                                                
(assert-template-wm-fact ?g                                                   
?*GOAL_ID_SLOTS*                                     
(delete-member$ (deftemplate-remaining-slots goal ?*GOAL_ID_SLOTS*)
meta-fact))                      
(assert-template-wm-fact ?gm                                                  
?*GOAL_META_ID_SLOTS*                                
(deftemplate-remaining-slots goal-meta ?*GOAL_META_ID_SLOTS*))
)

看看第3-6帧,我认为很明显,在该规则中唯一考虑的NeqFunction是(neq ?parent ?other-parent),这应该是一个相当简单的检查。

但这也是我被卡住的地方,因为其余的回溯都很奇怪。我在剪辑6.3的源代码中找不到函数PropagateReturnValuePropagateReturnAtom,但它们只出现在剪辑6.24中。因此,debuginfo中的某些内容似乎有些奇怪。我非常确信运行的剪辑版本确实是6.3 tho,因为我们使用了foreach循环。它也不可能是更高的版本,因为我验证了6.31中的功能确实缺失(例如,修改撤回的事实尚未导致错误)。

第3帧

(gdb) frame 3                                                                   
#3  0x00007f335436a839 in NeqFunction (theEnv=0x7f339c6e0970) at /usr/src/debug/clips-6.30.0-0.25.20090722svn.fc35.x86_64/clips/prdctfun.c:167
167!   EvaluateExpression(theEnv,theExpression,&item);                          
(gdb) info args                                                                 
theEnv = 0x7f339c6e0970                                                         
(gdb) info locals                                                               
item = {supplementalInfo = 0x7f339c7d3760, type = 0, value = 0x25, begin = 139859644516720, end = 139857960488192, next = 0x7f333e7fb370}
nextItem = {supplementalInfo = 0x7f339c6e0970, type = 2, value = 0x7f33399bdd90, begin = 139858433126066, end = 19, next = 0x7f33380d0002}
numArgs = 2                                                                     
i = <optimized out>                                                             
theExpression = 0x7f33380e3ca0
// i want find out what is evaluated in the Neq function
// from the source code I guessed I need to look at the evaluation data #define EVALUATION_DATA 44                                                  
(gdb)  p (((struct environmentData *) theEnv)->theData[44])                     
$93 = (void *) 0x7f339c6ab930                                                   
(gdb) p (struct evaluationData) *0x7f339c6ab930                                 
$95 = {CurrentExpression = 0x7f33380e3c80, EvaluationError = 0, HaltExecution = 0, CurrentEvaluationDepth = 2, numberOfAddressTypes = 1, PrimitivesArray = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f339c6feba0, 0x7f339c7bc398,
0x0 <repeats 23 times>, 0x7f339c70b530, 0x7f339c7213f0, 0x7f339c6fa058, 0x0 <repeats 16 times>, 0x7f339c7b6490, 0x7f339c7b63b0, 0x7f339c7b6420, 0x7f339c7b6570, 0x7f339c7b6260, 0x7f339c7b62d0, 0x7f339c7b6340, 0x7f339c7b6110,
0x7f339c7b6180, 0x7f339c7b61f0, 0x7f339c7b65e0, 0x7f339c7b6650, 0x7f339c7b6500, 0x7f339c796480, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f339c7d16e0, 0x7f339c7d1750, 0x7f339c7d1600, 0x7f339c7d1670, 0x7f339c7d1830, 0x7f339c7d17c0,
0x7f339c7d18a0, 0x7f339c7d19f0, 0x7f339c7d1910, 0x7f339c7d1a60, 0x7f339c7d1980, 0x7f339c7d1ad0, 0x7f339c7b9540, 0x7f339c700a30, 0x7f339c700aa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f339c6fa0c8, 0x0, 0x0, 0x0, 0x0, 0x7f339c7d2678,
0x7f339c7d26e8, 0x7f339c7d2758, 0x7f339c7d27c8, 0x0 <repeats 51 times>}, ExternalAddressTypes = {0x7f339c6aa790, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
// The current expression (CurrentExpression = 0x7f33380e3c80) should be Neq
// (type 30 is #define FCALL 30
(gdb) p (expr) *0x7f33380e3c80                                                  
$96 = {type = 30, value = 0x7f339c6aebb0, argList = 0x7f33380e3ca0, nextArg = 0x0}
// This seems to be true:
(gdb) p (struct FunctionDefinition) *0x7f339c6aebb0
$6 = {callFunctionName = 0x7f339c6aec10, actualFunctionName = 0x7f33543c38e3 "NeqFunction", returnValueType = 98 'b', functionPointer = 0x7f335436a7b0 <NeqFunction>, parser = 0x0, restrictions = 0x7f33543c38be "2*", overloadable = 1,
sequenceuseok = 1, environmentAware = 1, bsaveIndex = 0, next = 0x7f339c6aeac0, usrData = 0x0, context = 0x0}
// So the arglist should tell me something about what is compared I assume:
(gdb) p (expr) *0x7f33380e3ca0                                                  
$98 = {type = 58, value = 0x7f339c80f0e0, argList = 0x0, nextArg = 0x7f33380e3cc0}
(gdb) p (expr) *0x7f33380e3ca0@2                                                
$99 = {{type = 58, value = 0x7f339c80f0e0, argList = 0x0, nextArg = 0x7f33380e3cc0}, {type = 57, value = 0x7f33380e26d0, argList = 0x0, nextArg = 0x0}}

现在我缺乏继续的知识,因为type = 57type = 58#define FACT_JN_VAR1 57#define FACT_JN_VAR2 58。据我所知,这意味着实际数据存储在evaluationDataPrimitivesArray中,但如果这是真的,我仍然无法弄清楚发生了什么

(gdb) frame 3                                                                   
(gdb) p ((struct evaluationData) *0x7f339c6ab930).PrimitivesArray[57]           
$6 = (struct entityRecord *) 0x7f339c7b6110                                     
(gdb) p (struct entityRecord) *0x7f339c7b6110                                   
$7 = {name = 0x7f33543bfb9c "FACT_JN_VAR1", type = 57, copyToEvaluate = 0, bitMap = 1, addsToRuleComplexity = 0, shortPrintFunction = 0x7f3354344e40 <PrintFactJNGetVar1>, longPrintFunction = 0x7f3354344e40 <PrintFactJNGetVar1>,
deleteFunction = 0x0, evaluateFunction = 0x7f335435bd70 <FactJNGetVar1>, getNextFunction = 0x0, decrementBusyCount = 0x0, incrementBusyCount = 0x0, propagateDepth = 0x0, markNeeded = 0x0, install = 0x0, deinstall = 0x0, usrData = 0x0}
(gdb) ptype entityRecord                                                        
(gdb) p ((struct evaluationData) *0x7f339c6ab930).PrimitivesArray[58]           
$8 = (struct entityRecord *) 0x7f339c7b6180                                     
(gdb) p (struct entityRecord) *0x7f339c7b6180                                   
$9 = {name = 0x7f33543bfba9 "FACT_JN_VAR2", type = 58, copyToEvaluate = 0, bitMap = 1, addsToRuleComplexity = 0, shortPrintFunction = 0x7f3354344e50 <PrintFactJNGetVar2>, longPrintFunction = 0x7f3354344e50 <PrintFactJNGetVar2>,
deleteFunction = 0x0, evaluateFunction = 0x7f335435b3e0 <FactJNGetVar2>, getNextFunction = 0x0, decrementBusyCount = 0x0, incrementBusyCount = 0x0, propagateDepth = 0x0, markNeeded = 0x0, install = 0x0, deinstall = 0x0, usrData = 0x0}

如果您使用的是CLIPS 6.3,但堆栈跟踪显示的是6.24中的函数,那么您可能应该先弄清楚。

然后,如果您还没有这样做,请从https://sourceforge.net/p/clipsrules/code/HEAD/tree/branches/63x/core/看看你的问题是否仍然存在。

我怀疑这是否是neq函数特有的问题。FACT_JN_VAR1和FACT_JN_VAR2是在模式匹配期间从事实中检索值的基元。有时,这可能是由于从事实中检索值的索引计算不正确造成的,并且通常与具有嵌套条件元素的复杂条件集的规则相关联。

由于故障是在断言wm事实时发生的,因此任何具有与该事实匹配的模式并在条件中具有neq调用的规则都可能是原因。有时,您可以通过运行系统直到触发最后一条规则来隔离问题,保存事实,再次清除并加载规则,加载保存的事实,然后让最后一条命令触发。如果你仍然遇到崩溃,那么你可以削减事实和规则,这样你就可以得到一组更小的代码来调试。

想到的另外两种可能性是,CLIPS错误地过早地进行垃圾收集,或者内存以其他方式损坏。这很难调试,因为实际问题通常发生在崩溃之前很久。当我以前不得不调试这些类型的问题时,第一步也是尝试减少代码,这样我就可以更好地了解问题的原因。

最新更新