2011-02-08 5 views
1

ここで何が起こっているかについて誰かが考えていますか?再帰的な関数があります。これは、時にはpcreを呼び出して、ビルド中の文字列内のパターンにマッチさせます。 (括弧はエスケープされた括弧もうまくいきます)パターンに括弧がない場合はうまく動作しますが、([az]などの)パターンを使用すると、valgrindは最も深い再帰関数が戻り値(パターン\([az] \)は正常に動作します):再帰関数でlibpcreを使用する

EDIT:再帰的なバージョンは書きませんでした。カッコがあり、私のルーチンの中の前の関数のアドレスを何とか使いこなしてしまうと、libpcreが再帰を使うことは可能でしょうか?

==4712== 1 errors in context 1 of 1: 
==4712== Jump to the invalid address stated on the next line 
==4712== at 0xFFFFFFFF: ??? 
==4712== by 0x40B646: ??? 
==4712== by 0x40B646: ??? 
==4712== by 0x40B646: ??? 
==4712== by 0x40B646: ??? 
==4712== by 0x40B483: ??? 
==4712== Address 0xffffffff is not stack'd, malloc'd or (recently) free'd 

linked_list_t *_GetExistingKeysByPattern(linked_list_t *keys, 
             session_t *session) 
{ 
    char *cKey; 
    linked_list_t *existingKeys = ListNew(NULL); 
    ListIterSet(keys); 
    while (cKey = ListIterNext(keys)) 
    { //cKey could be SOFTWARE\\something\\([0-9]\.1) for example 
     char keyPath[512]; 
     keyPath[0] = '\0'; 
     _GetExistingKeysByPatternHelper(cKey, keyPath, existingKeys, session); 
    } 
    return existingKeys; 
} 


void _GetExistingKeysByPatternHelper(char *patternStart, 
            char *keyPath, 
            linked_list_t *existing, 
            session_t *session) 
{ 
    char *ptr, currentKeyPath[512]; 
    unsigned short endOfPattern = 0; 
    char *patternStartCopy = strdup(patternStart); 

    if (ptr = strstr(patternStartCopy, "\\\\")) 
     *ptr = '\0'; 
    else 
     endOfPattern = 1; 

    snprintf(currentKeyPath, 
      512, 
      "%s%s%s", 
      keyPath, 
      keyPath[0] == '\0' ? "" : "\\", 
      patternStartCopy[0]=='^'?patternStartCopy+1:patternStartCopy); 

    if (OpenRegistryEntry(session, currentKeyPath)) 
    { 
     if (!endOfPattern) 
      _GetExistingKeysByPatternHelper(ptr + 2, 
              currentKeyPath, 
              existing, 
              session); 
     else 
      ListInsert(existing, (void *) strdup(currentKeyPath)); 
    } 
    else if (keyPath[0] != '\0') 
    { 
     // Potential pattern 
     if (OpenRegistryEntry(session, keyPath)) 
     { 
      char *subKey; 
      unsigned short i = 0; 
      while (subKey = EnumerateRegistry(session, i++)) 
      { 
       if (PatternEval(subKey, patternStartCopy, 1)) 
       { 
        char keyPathCopy[512]; 
        snprintf(keyPathCopy, 
          512, 
          "%s\\%s", 
          keyPath, 
          subKey); 

        if (!endOfPattern) 
        { 
         _GetExistingKeysByPatternHelper(ptr + 2, 
                 keyPathCopy, 
                 existing, 
                 session); 
         OpenRegistryEntry(session, keyPath); 
        } 
        else 
         ListInsert(existing, (void *) strdup(keyPathCopy)); 
       } 
       free(subKey); 
      } 
     } 
    } 
    free(patternStartCopy); 
} 

unsigned short PatternEval(char *str, char *pattern, unsigned short carrot) 
{ 
    unsigned short res = 0; 
    const char *error; 
    int erroroffset, rc, i; 
    pcre *re; 
    int ovector[100]; 
    char *tmp; 
    if (carrot) 
    { 
     if (*pattern == '^') pattern++; 
     tmp = (char *) malloc (strlen(pattern) + 2); 
     sprintf(tmp, "^%s", pattern); 
    } 
    else 
     tmp = pattern; 

    if(re = pcre_compile(tmp, PCRE_CASELESS, &error, &erroroffset, 0)) 
    { 
     if ((rc = pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector))) >= 0) 
      res = 1; 
     pcre_free(re); 
    } 
    else 
     printf("pcre_compile failed (offset %d), %s\n",erroroffset,error); 

    if (carrot) 
     free(tmp); 

    return res; 
} 
+0

コードを投稿してください。私たちは霊的ではありません。 –

答えて

2

ここで最後のパラメータは、少なくとも間違っている:

pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector)) 

はsizeof(ovector)バイト単位のサイズを与えるが、pcre_exec intの数を必要とするので、

pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector)/sizeof(ovector[0])) 
にそれを変更

ドキュメントも

ovecsize  Number of elements in the vector (a multiple of 3) 
述べて

サイズは3の倍数であるはずですが、この部分はかなり不明です。