tags 446785 + patch thanks On Tue, Oct 16, 2007 at 12:00:23AM +0100, Francis Tyers wrote: > > > > > Program terminated with signal 11, Segmentation fault. > > #0 ~ApertiumRE (this=0x7fff00000000) at apertium_re.cc:17 > > 17 if(!empty) > > (gdb) bt > > #0 ~ApertiumRE (this=0x7fff00000000) at apertium_re.cc:17 > > #1 0x00002ad2c9d9e594 in TransferData::writeRegexps ( > > this=<value optimized out>, output=0xb2cb20) at transfer_data.cc:185 > > #2 0x00002ad2c9d9e6e0 in TransferData::write (this=0x7fffe0fa6918, > > output=0xb2cb20) at transfer_data.cc:142 > > #3 0x00002ad2c9da560d in TRXReader::write (this=0x7fffe0fa68d0, > > [EMAIL PROTECTED]) at trx_reader.cc:328 > > #4 0x0000000000400f4f in main (argc=<value optimized out>, > > argv=0x7fffe0fa6c28) at transferpp.cc:40 > > (gdb) p empty > > Cannot access memory at address 0x7fff00000000 > > (gdb) p &empty > > $1 = (bool *) 0x7fff00000000
So, I've been looking at it, and I found a few problems: - You're using new char[size] to allocate something but using "delete" instead of delete [] to free it. - The same variable can also be allocated by pcre_malloc() but you still "delete" it instead of calling pcre_free(). - You call pcre_fullinfo() with "what" set to PCRE_INFO_SIZE, which expects a size_t *, but you pass it an int *. On 64 bit arches this will of course overwrite things it shouldn't. - fwrite() also returns a size_t instead of an int. I've solved the first 2 by using pcre_malloc() instead of new, which really is what you should be doing. I think you're just lucky that things don't randomly break. The other was just replacing int with size_t. patch is attached. Kurt
--- apertium/apertium_re.cc.old 2007-10-16 19:06:54.000000000 +0200 +++ apertium/apertium_re.cc 2007-10-16 21:42:45.000000000 +0200 @@ -16,7 +16,7 @@ { if(!empty) { - delete reinterpret_cast<char *>(re); + pcre_free(re); } empty = true; } @@ -25,7 +25,7 @@ ApertiumRE::read(FILE *input) { unsigned int size = Compression::multibyte_read(input); - re = reinterpret_cast<pcre *>(new char[size]); + re = static_cast<pcre *>(pcre_malloc(size)); if(size != fread(re, 1, size, input)) { cerr << L"Error reading regexp" << endl; @@ -61,7 +61,7 @@ exit(EXIT_FAILURE); } - int size; + size_t size; int rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); if(rc < 0) { @@ -71,8 +71,8 @@ Compression::multibyte_write(size, output); - rc = fwrite(re, 1, size, output); - if(rc != size) + size_t rc2 = fwrite(re, 1, size, output); + if(rc2 != size) { wcerr << L"Error writing precompiled regex\n" << endl; exit(EXIT_FAILURE);