Jonas Osburg
Jonas Osburg

Reputation: 1783

signal 11 (SIGSEGV)

I wrote the following code:

FILE *book;
wchar_t bufferln[FILE_READ_BUFFER];
wchar_t buffer[FILE_READ_BUFFER];
book = fopen(file, "r");
if(book == NULL){
    perror("Es ist ein Fehler beim lesen des Buches aufgetreten");
    return EXIT_FAILURE;
}
while(fgetws(buffer, FILE_READ_BUFFER, book) != NULL){
    if(wcscmp(buffer, L"\n") == 0){
        bufferln[0] = L'\0';
        continue;
    }
    buffer[wcsnlen(buffer, FILE_READ_BUFFER)-1] = L' ';
    wcsncat(bufferln, buffer, FILE_READ_BUFFER);
}
return EXIT_SUCCESS;

It crashes with SIGSEGV. I ran valgrind which shows the following:

==11251== Conditional jump or move depends on uninitialised value(s)
==11251==    at 0x40BD5CF: wcsncat (wcsncat.c:36)
==11251==    by 0x804865D: read_book (book.c:18)
==11251==    by 0x804872B: main (main.c:19)
==11251==  Uninitialised value was created by a stack allocation
==11251==    at 0x80485B7: read_book (book.c:3)
==11251== 
==11251== Invalid read of size 4
==11251==    at 0x40A58E2: fgetws (iofgetws.c:52)
==11251==    by 0x804867D: read_book (book.c:12)
==11251==    by 0x6D: ???
==11251==  Address 0x65 is not stack'd, malloc'd or (recently) free'd
==11251== 
==11251== 
==11251== Process terminating with default action of signal 11 (SIGSEGV)
==11251==  Access not within mapped region at address 0x65
==11251==    at 0x40A58E2: fgetws (iofgetws.c:52)
==11251==    by 0x804867D: read_book (book.c:12)
==11251==    by 0x6D: ???
==11251==  If you believe this happened as a result of a stack
==11251==  overflow in your program's main thread (unlikely but
==11251==  possible), you can try to increase the size of the
==11251==  main thread stack using the --main-stacksize= flag.
==11251==  The main thread stack size used in this run was 8388608.

I think the problem is somehow related to my usage of wcsncat (writing into *book memory maybe?) but why? I want to read a document (UTF-8) paragraph by paragraph and then do stuff that is not in this code yet.

Upvotes: 2

Views: 25879

Answers (3)

Anoop Menon
Anoop Menon

Reputation: 637

What could be happening is that your wcsncat() which as per documentation does :

" DESCRIPTION The wcsncat() function appends no more than the first n characters of the string pointed to by ws2 to the end of the string pointed to by ws1. If a NULL character appears in ws2 before n characters, all characters up to the NULL character are appended to ws1. The first character of ws2 overwrites the terminating NULL character of ws1. A NULL terminating character is always appended to the result, and if the objects used for copying overlap, the behavior is undefined. "

So it keeps appending to bufferln starting by overwriting the first occurence of NULL character. So in cases where if(wcscmp(buffer, L"\n") == 0) returns FALSE you will end up overrunning your allocated buffer of FILE_READ_BUFFER and spill the file outside the bufferln boundary and possibly end up corrupting the stack.

In most cases stacks grow downwards and it must have reached some regions which actually FAULT because accessing the first 2 pages of your virtual address pages is not allowed on most systems. This is a moot point as to why it faulted there. But the main reason is that you have to try write the data somewhere once you have read it as your read and write buffers are of the same length.

HTH

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 754910

You don't initialize bufferln, so you've no idea where your code is going to write when you concatenate (wcsncat()) the new line to the end of the uninitialized data.

You also write a (wide) space over the null terminator at the end of the input buffer buffer, so you've no idea what is going to be copied into the random location; copying will stop when it next hits a wide NUL.

Upvotes: 2

wildplasser
wildplasser

Reputation: 44250

If the line is empty (\n gets replaced by \0) , the string length is null, and strlen() -1 points below the buffer.

EDIT: I got it wrong; you are just appending too much. Increase your buffer size, read shorter lines, or both. And avoid strcat();

Upvotes: 0

Related Questions