11

So I believe this is just a problem on unix and that it occurs at the first fscanf if the Clion debugger was right, but I don't know why I get the error- Process finished with exit code 139 (interrupted by signal 11: SIGSEGV) - why?

struct loginInformation
{
    char username[USERNAME_LENGTH];
    char password[PASSWORD_LENGTH];
    int type;
}accounts[NUM_OF_ACCOUNTS];

void createAccountsFromFile()
{
    FILE *input = fopen("accounts.txt", "r");
    int counter;
    for(counter = 0; counter < NUM_OF_ACCOUNTS; counter++)
    {
        fscanf(input, "%s", accounts[counter].username);
        fscanf(input, "%s", accounts[counter].password);
        fscanf(input, "%d", &accounts[counter].type);
    }
}

int main()
{
    createAccountsFromFile();
}

accounts.txt

user1
pass1
0
user2
pass2
1
user3
pass3
2
user4
pass4
3
michael lee
  • 331
  • 2
  • 3
  • 9
  • 2
    check 1) return value of `fopen`. (Is the file in a relative path accessible? Or do you have access authority?...). 2) Is there data that causes buffer overflow in reading? – BLUEPIXY Mar 19 '17 at 02:22
  • 2
    this line: `for(counter = 0; counter < NUM_OF_ACCOUNTS; counter++)` contains the assumption that there will be exactly `NUM_OF_ACCOUNTS` accounts in the input file. That is a very 'iffy' assumption. Much better to use something like: `counter =0; while( fscanf( input, "%s", accounts[counter].username) == 1)` however, even that is weak because any one line may not contain all three data items. AND '%s" can overflow the input buffer, Which is undefined behavior and can lead to a seg fault event. – user3629249 Mar 19 '17 at 02:27
  • 2
    Lets say that USERNAME_LEN is 20 for the following: when calling any of the `scanf()` family of functions,1) always check the returned value, not the parameter value to assure the operation was successful. 2) when using the '%s' input/conversion specifier, always include a MAX CHARACTERS modifier that is 1 less than the length of the input buffer to avoid any buffer overflow. I.E. `if( fscanf(input, " %19s", accounts[counter].username) != 1 ) { perror( "fscanf for user name failed" ); exit( EXIT_FAILURE ); }` – user3629249 Mar 19 '17 at 02:32
  • 1
    @user3629249 To further clarify, NUM_OF_ACCOUNTS = 4, and their are 12 lines of text in the text file, is fscanf reading line by line here – michael lee Mar 19 '17 at 02:52
  • @michaellee If file is accessible then there should not be any issue with 'fopen'; but in your program you have to close the file descriptor as 'fclose(input)'. – vinod maverick Mar 19 '17 at 04:20
  • @user3629249: Note that in general, `fscanf()` can return 0 which means there was no error to be reported by `perror()`, but the input data didn't match the conversion specification. With a string, pretty much anything is OK, so that won't be a problem, but with numeric conversion specifications, it definitely can be (the user types `z` instead of a digit, for example). – Jonathan Leffler Mar 19 '17 at 06:57
  • when `fscanf()` returns 0 that means that the 'first' input/conversion specification failed. It does NOT mean there was no error. – user3629249 Mar 19 '17 at 09:11

4 Answers4

7

It means the program crashed before it exited. You need to debug the program. For example, you need to check whether the file is successfully opened after fopen.

xuhdev
  • 8,018
  • 2
  • 41
  • 69
  • 1
    Yeah, the file wasn't opening. I had to specify the working directory by editing the configuration, then it worked. – michael lee Mar 19 '17 at 20:54
2

SIGSEGV are not always thrown due to a root cause of memory access problems...

Perl throws a 139 on Unix usually because of file I/O. You might have accidentally deleted your input files.

user7610
  • 25,267
  • 15
  • 124
  • 150
BAMF4bacon
  • 523
  • 1
  • 7
  • 21
1

TL;DR: Your program tried to access a memory location it had no permissions to access, so the operating system killed it.


First: The code "139" doesn't matter, forget about the number. Your program was terminated after "getting a SIGSEGV", or a signall regarding a segmentation violation. Read about what that means here:

What causes a SIGSEGV

(never mind that question is about C++, same idea.)

Now, why would this happen? You must be making some assumptions you shouldn't be. Looking at your code, it might be:

  • Reading a very long string from the file which exceeds the bounds of the loginInformation array - and perhaps even the bounds of the memory region allocated to your program overall.
  • Scanning from an invalid-state/uninitialized/null file descriptor, as in @xuhdev's answer
  • (Unlikely/impossible) Ignoring some error generated by one of the fscanf() calls (you need to check errno if a scan failed).

I think that covers it although maybe I missed something. Instead of speculating you can actually check what happened using a debugger on the core dump:

How do I analyze a program's core dump file with GDB when it has command-line parameters?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
-1

On Perl programmation RC 139 caused by "Out of memory" for me. Because there have been too much data in a variable (millions). I have done a segmentation manualy by release (undef) this variable regularly. This solved this.

ZAIL
  • 1
  • 2