0

アプリケーションでBoehmC++ガベージコレクターを使用しています。このアプリケーションは、レーベンシュタイン決定性有限オートマトンPythonプログラムを使用して、2つの文字列間のレーベンシュタイン距離を計算します。gcc4.1.2を使用してCentosLinuxのバージョンでPythonプログラムをC++に移植しました。

最近、アプリケーションを10分以上実行した後、SIGABRTエラーメッセージが表示されることに気付きましたToo many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS。誰かがこの問題を修正または回避する方法を知っているかどうか疑問に思いました。

これが私のgdbスタックトレースです。ありがとうございました。

  Program received signal SIGABRT, Aborted.
(gdb) bt
#0  0x002ed402 in __kernel_vsyscall ()
#1  0x00b1bdf0 in raise () from /lib/libc.so.6
#2  0x00b1d701 in abort () from /lib/libc.so.6
#3  0x00e28db4 in GC_abort (msg=0xf36de0 "Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS")
    at ../Source/misc.c:1079
#4  0x00e249a0 in GC_add_to_heap (p=0xb7cb7000, bytes=65536) at ../Source/alloc.c:812
#5  0x00e24e45 in GC_expand_hp_inner (n=16) at ../Source/alloc.c:966
#6  0x00e24fc5 in GC_collect_or_expand (needed_blocks=1, ignore_off_page=0) at ../Source/alloc.c:1032
#7  0x00e2519a in GC_allocobj (sz=6, kind=1) at ../Source/alloc.c:1087
#8  0x00e31e90 in GC_generic_malloc_inner (lb=20, k=1) at ../Source/malloc.c:138
#9  0x00e31fde in GC_generic_malloc (lb=20, k=1) at ../Source/malloc.c:194
#10 0x00e322b8 in GC_malloc (lb=20) at ../Source/malloc.c:319
#11 0x00df5ab5 in gc::operator new (size=20) at ../Include/gc_cpp.h:275
#12 0x00de7cb7 in __automata_combined_test2__::DFA::levenshtein_automata (this=0xb7b49080, term=0xb7cb5d20, k=1) 
at ../Source/automata_combined_test2.cpp:199
#13 0x00e3a085 in cDedupe::AccurateNearCompare (this=0x8052cd8, 
    Str1_=0x81f1a1d "GEMMA     OSTRANDER GEM 10   
DICARLO", ' ' <repeats 13 times>, "01748SUE       WOLFE     SUE 268  POND", ' ' <repeats 16 times>, 
"01748REGINA    SHAKIN    REGI16   JAMIE", ' ' <repeats 15 times>, "01748KATHLEEN  MAZUR     CATH10   JAMIE    "
..., 
    Str2_=0x81f2917 "LINDA     ROBISON   LIN 53   CHESTNUT", ' ' <repeats 12 times>, 
"01748MICHELLE  LITAVIS   MICH15   BLUEBERRY", ' ' <repeats 11 times>, "01748JOAN      TITUS     JO  6    SMITH", 
' ' <repeats 15 times>, "01748MELINDA   MCDOWELL  MEL 24   SMITH    "..., Size_=10, 

アップデート:

BoehmガベージコレクタのソースファイルとヘッダーファイルをToo many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS調べたところ、GNUmakefileのCFLAGSセクションに‑DLARGE_CONFIGを追加することで、次のエラーメッセージを修正できることがわかりました。

GNUmakfileに対するこの変更をテストしたところ、Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTSエラーメッセージが表示されなくなったことがわかりました。ただし、新しいセグメンテーション違反(コアダンプ)が発生しています。gdbを使用すると、GDBセグメンテーション違反が20行目の次の関数で発生していることがわかりました(注釈を付けました)。

set<tuple2<__ss_int, __ss_int> *> *NFA::next_state(set<tuple2<__ss_int, __ss_int> *> *states, str *input) {
    tuple2<__ss_int, __ss_int> *state;
    set<tuple2<__ss_int, __ss_int> *>::for_in_loop __3;
    set<tuple2<__ss_int, __ss_int> *> *__0, *dest_states;
    dict<str *, set<tuple2<__ss_int, __ss_int> *> *> *state_transitions;
    __iter<tuple2<__ss_int, __ss_int> *> *__1;
    __ss_int __2;

    dest_states = (new set<tuple2<__ss_int, __ss_int> *>());

    FOR_IN_NEW(state,states,0,2,3)
        state_transitions = (this->transitions)->get(state, ((dict<str *, set<tuple2<__ss_int, __ss_int> *> *> *)((new dict<void *, void *>()))));

    dest_states->update(state_transitions->get(input, new set<tuple2<__ss_int, __ss_int> *>()));
    dest_states->update(state_transitions->get(NFA::ANY, new set<tuple2<__ss_int, __ss_int> *>()));
    END_FOR

    return (new set<tuple2<__ss_int, __ss_int> *>(this->_expand(dest_states),1));//line20  
}

セグメンテーション違反を修正するためにこの関数を変更することは可能かどうか疑問に思いました。ありがとうございました。

4

1 に答える 1

2

私は最終的に、メモリセグメンテーション違反の GC を修正することを考え出しました。Python プログラムの setdefault と get 構造を置き換えました。たとえば、self.transitions.setdefault(src, {}).setdefault(input, set()).add(dest) python ステートメントを次のように置き換えました。

 if src not in self.transitions:
    self.transitions[src] = {}
 result = self.transitions[src]
 if input not in result:
    result[input] = set()
 result[input].add(dest)

また、python ステートメントを次のように置き換えました。

new_states = self.transitions.get(state, {}).get(NFA.EPSILON, set()).difference(states)

と:

        if state not in self.transitions:
           self.transitions[state] = {}
        result = self.transitions[state]    
        if NFA.EPSILON not in result:
           result[NFA.EPSILON] = set()
        cook = result[NFA.EPSILON]      
        new_states = cook.difference(states) 

最後に__shedkin__.init()、for または while ループの外に置くようにしました。__shedskin__.init()GC アロケータを呼び出します。これらすべての変更の目的は、GC アロケータへの負担を軽減することです。

これらの変更を GC アロケータへの 300 万回の呼び出しでテストしましたが、まだセグメンテーション エラーは発生していません。ありがとうございました。

于 2011-02-07T16:35:24.800 に答える