This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
segmentation fault after some modification about regex operation of glibc-2.7
- From: peng yang <peterpy8 at gmail dot com>
- To: libc-help at sourceware dot org
- Date: Fri, 26 Aug 2011 07:00:06 +0800
- Subject: segmentation fault after some modification about regex operation of glibc-2.7
- References: <CA+0cCEJKh7zEuE2uTyA-JnHAqmNfGdOVQjfR-Tc8_Q8WMEG+Qw@mail.gmail.com>
I am a new guy doing glibc dev, so my question may seem silly.
In order to get one transition table just
like(http://lambda.uta.edu/cse5317/notes/node8.html) related to one
regular expression. I add an interface
âint regtrtable (const regex_t *__restrict __preg, char * trantable,
int *state_num_ptr);â in regex.h. It compiles well. However, after
make install, lots of segmentation fault come to the screen. And I
don't know how to rescue my OS. Besides, my modification patch will be
added below. I hope you guys can help me figure out that some mistakes
there may be.
diff -r ace192926b61 -r b5b99be08504 posix/regex.h
--- a/posix/regex.h   Mon Aug 22 07:38:59 2011 -0400
+++ b/posix/regex.h   Tue Aug 23 02:39:37 2011 -0400
@@ -533,6 +533,11 @@
Â# endif
Â#endif
+/* Added by peter for opencl acceleration */
+extern int regtrtable (const regex_t *__restrict __preg, char *
trantable, int *state_num_ptr);
+
+extern int freetrtable (char * trantable);
+
Â/* POSIX compatibility. Â*/
Âextern int regcomp (regex_t *__restrict __preg,
         Âconst char *__restrict __pattern,
diff -r ace192926b61 -r b5b99be08504 posix/regex_internal.c
--- a/posix/regex_internal.c  ÂMon Aug 22 07:38:59 2011 -0400
+++ b/posix/regex_internal.c  ÂTue Aug 23 02:39:37 2011 -0400
@@ -30,6 +30,52 @@
                    Âunsigned int context,
                    Âunsigned int hash) internal_function;
+/* Function to build the global transition table */
+linklist * init_state_linklist(void)
+{
+ Â Âlinklist *p;
+ Â Âp = (linklist *)malloc(sizeof(linklist));
+ Â Âp ->next = NULL;
+ Â Âr = p;
+ Â Âreturn p;
+}
+
+void insert_state_linklist(re_dfastate_t *state)
+{
+ Â Âcur_state_linklist = (linklist *)malloc(sizeof(linklist));
+ Â Âcur_state_linklist -> state = state;
+ Â Âcur_state_linklist -> next = NULL;
+ Â Âr -> next = cur_state_linklist;
+ Â Âr = cur_state_linklist;
+ Â Âreturn;
+}
+
+void destroy_state_linklist(void)
+{
+ Â Âlinklist *p = state_linklist_head, *q = p -> next;
+ Â Âwhile(q != NULL)
+ Â Â{
+ Â Â Â Âfree(p);
+ Â Â Â Âp = q;
+ Â Â Â Âq = p -> next;
+ Â Â}
+ Â Âfree(p);
+
+}
+
+void disp_state_linklist(void)
+{
+ Â Âlinklist *p = state_linklist_head->next;
+ Â Âprintf("\nstate_id_size = %d.", state_id_count);
+
+ Â Âwhile(p != NULL)
+ Â Â{
+ Â Â Â Âprintf("\nstateid: %d", p->state->state_id);
+ Â Â Â Âp = p->next;
+ Â Â}
+ Â Âreturn;
+}
+
Â/* Functions for string operation. Â*/
Â/* This function allocate the buffers. ÂIt is necessary to call
@@ -1488,6 +1534,7 @@
 if (BE (new_state == NULL, 0))
  *err = REG_ESPACE;
+ Âinsert_state_linklist(new_state);
 return new_state;
Â}
@@ -1531,6 +1578,7 @@
 if (BE (new_state == NULL, 0))
  *err = REG_ESPACE;
+ Âinsert_state_linklist(new_state);
 return new_state;
Â}
@@ -1611,6 +1659,7 @@
  }
 newstate->entrance_nodes = &newstate->nodes;
+ Ânewstate->state_id = get_state_id();
 for (i = 0 ; i < nodes->nelem ; i++)
  {
   re_token_t *node = dfa->nodes + nodes->elems[i];
@@ -1662,6 +1711,7 @@
 newstate->context = context;
 newstate->entrance_nodes = &newstate->nodes;
+ Ânewstate->state_id = get_state_id();
 for (i = 0 ; i < nodes->nelem ; i++)
  {
diff -r ace192926b61 -r b5b99be08504 posix/regex_internal.h
--- a/posix/regex_internal.h  ÂMon Aug 22 07:38:59 2011 -0400
+++ b/posix/regex_internal.h  ÂTue Aug 23 02:39:37 2011 -0400
@@ -497,6 +497,7 @@
 re_node_set inveclosure;
 re_node_set *entrance_nodes;
 struct re_dfastate_t **trtable, **word_trtable;
+ Âunsigned short int state_id;
 unsigned int context : 4;
 unsigned int halt : 1;
 /* If this state can accept `multi byte'.
@@ -509,6 +510,18 @@
Â};
Âtypedef struct re_dfastate_t re_dfastate_t;
+typedef struct lnode
+{
+ Â Âre_dfastate_t *state;
+ Â Âunsigned short int trtable[256];
+ Â Âunsigned short int final; /*final == 1, lnode is final state. */
+ Â Âstruct lnode *next;
+}linklist;
+
+unsigned int state_id_count;
+linklist *state_linklist_head;
+linklist *r = NULL , *cur_state_linklist = NULL;
+
Âstruct re_state_table_entry
Â{
 int num;
@@ -684,6 +697,21 @@
 } opr;
Â} bracket_elem_t;
+static inline void init_state_id_count(void)
+{
+ Â Âstate_id_count = 0;
+}
+
+static inline unsigned int get_state_id(void)
+{
+ Â Âstate_id_count++;
+ Â Âreturn state_id_count;
+}
+
+linklist * init_state_linklist(void);
+void insert_state_linklist(re_dfastate_t * state);
+void destroy_state_linklist(void);
+void disp_state_linklist(void);
Â/* Inline functions for bitset operation. Â*/
Âstatic inline void
diff -r ace192926b61 -r b5b99be08504 posix/regexec.c
--- a/posix/regexec.c  Mon Aug 22 07:38:59 2011 -0400
+++ b/posix/regexec.c  Tue Aug 23 02:39:37 2011 -0400
@@ -41,6 +41,8 @@
                    int start, int range, int stop,
                    size_t nmatch, regmatch_t pmatch[],
                    int eflags) internal_function;
+static reg_errcode_t regtrtable_internal (const regex_t *preg,
+ Â Â Â Â Â Â Â Â Â Â char * trantable, int *state_num_ptr) internal_function;
Âstatic int re_search_2_stub (struct re_pattern_buffer *bufp,
              const char *string1, int length1,
              const char *string2, int length2,
@@ -127,6 +129,10 @@
Âstatic re_dfastate_t *transit_state (reg_errcode_t *err,
                  re_match_context_t *mctx,
                  re_dfastate_t *state) internal_function;
+static re_dfastate_t *transit_state_by_char (reg_errcode_t *err,
+ Â Â Â Â Â Â Â Â Â Â re_dfa_t *dfa,
+ Â Â Â Â Â Â Â Â Â Â unsigned char ch,
+ Â Â Â Â Â Â Â Â Â Â re_dfastate_t *state) internal_function;
Âstatic re_dfastate_t *merge_state_with_log (reg_errcode_t *err,
                     Âre_match_context_t *mctx,
                     Âre_dfastate_t *next_state)
@@ -200,7 +206,38 @@
  Âinternal_function;
Âstatic reg_errcode_t extend_buffers (re_match_context_t *mctx)
  Âinternal_function;
-
+
+/* Added by peter for opencl acceleration
+ * return 0: success
+ * return 1: non-success
+ * */
+int
+regtrtable (preg, trantable, state_num_ptr)
+ Â Âconst regex_t *__restrict preg;
+ Â Âchar * trantable;
+ Â Âint * state_num_ptr;
+{
+ Â Âreg_errcode_t err;
+ Â Âre_dfa_t *dfa = (re_dfa_t *)preg->buffer;
+
+ Â Â__libc_lock_lock (dfa->lock);
+
+ Â Âerr = regtrtable_internal(preg, trantable, state_num_ptr);
+
+ Â Â__libc_lock_unlock (dfa->lock);
+
+ Â return err != REG_NOERROR;
+}
+
+int
+freetrtable (trantable)
+ Â Âchar * trantable;
+{
+ Â Âfree(trantable);
+ Â Âreturn 0;
+}
+
+
Â/* Entry point for POSIX code. Â*/
Â/* regexec searches for a given pattern, specified by PREG, in the
@@ -607,6 +644,51 @@
Â/* Internal entry point. Â*/
+static reg_errcode_t
+regtrtable_internal(preg, trantable, state_num_ptr)
+ Â Âconst regex_t *preg;
+ Â Âchar * trantable;
+ Â Âint * state_num_ptr;
+{
+ Â Âunsigned char ch = 0;
+ Â Âint i, item_size;
+ Â Âreg_errcode_t err;
+ Â Âre_dfastate_t * cur_state, * new_state;
+ Â Âre_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ Â Âerr = REG_NOERROR;
+ Â Âstate_linklist_head = init_state_linklist();
+
+ Â Âcur_state = dfa->init_state;
+ Â Âinsert_state_linklist(cur_state);
+
+ Â Âwhile(cur_state_linklist -> next != NULL)
+ Â Â{
+ Â Â Â Âfor(i = 0; i < 256; i++)
+ Â Â Â Â{
+ Â Â Â Â Â Ânew_state = transit_state_by_char(&err, dfa, ch, cur_state);
+
+ Â Â Â Â Â Âcur_state_linklist->trtable[ch] = new_state->state_id;
+ Â Â Â Â Â Âcur_state_linklist->final =
cur_state_linklist->state->halt ? 1 : 0;
+ Â Â Â Â Â Âch ++;
+ Â Â Â Â}
+
+ Â Â Â Âcur_state = cur_state_linklist -> next -> state;
+ Â Â}
+ Â Âstate_num_ptr[0] = state_id_count;
+
+ Â Âitem_size = 257 * sizeof(unsigned short int);
+ Â Âtrantable = (char *)malloc(state_id_count * item_size);
+
+ Â Âcur_state_linklist = state_linklist_head -> next;
+ Â Âfor(i=0; i< state_id_count; i++)
+ Â Â{
+ Â Â Â Âmemcpy(trantable + i * item_size,
cur_state_linklist->trtable, item_size);
+ Â Â Â Âcur_state_linklist = cur_state_linklist -> next;
+ Â Â}
+
+ Â Âdestroy_state_linklist();
+}
+
Â/* Searches for a compiled pattern PREG in the string STRING, whose
 Âlength is LENGTH. ÂNMATCH, PMATCH, and EFLAGS have the same
 Âmingings with regexec. ÂSTART, and RANGE have the same meanings
@@ -2295,6 +2377,31 @@
  }
Â}
+static re_dfastate_t *
+internal_function
+transit_state_by_char (reg_errcode_t *err,
+ Â Â Â Â Â Â Â Â Â Â Â re_dfa_t *dfa,
+ Â Â Â Â Â Â Â Â Â Â Â unsigned char ch,
+ Â Â Â Â Â Â Â Â Â Â Â re_dfastate_t *state)
+{
+ Âre_dfastate_t **trtable;
+
+ Â/* Use transition table Â*/
+ Âfor (;;)
+ Â{
+ Â Â Âtrtable = state->trtable;
+ Â Â Âif (BE (trtable != NULL, 1))
+ Â Â Â Â Âreturn trtable[ch];
+
+ Â Â Âif (!build_trtable (dfa, state))
+ Â Â Â{
+ Â Â Â Â Â*err = REG_ESPACE;
+ Â Â Â Â Âreturn NULL;
+ Â Â Â}
+
+ Â Â Â/* Retry, we now have a transition table. Â*/
+ Â}
+}
Â/* Update the state_log if we need */
Âre_dfastate_t *
Âinternal_function