Segment Fault after producing debug information

Segment Fault after producing debug information


Hi,

    When compiling the following program without the -g parameter, the run result is -1. After the -g parameter is added, the run result is reported as a Segment Fault. Perhaps intelc has some optimizations by default. Is this a correct behavior for intel c complier?

 

TestCase:

#include<stdio.h>

#include<string.h>

int has_8bit(int i)

{

    return strcmp(i, "none");

}

int main(void){

    int NISLParameter0 = -4569;

    int NISLParameter1 = has_8bit(NISLParameter0);

    printf("%d",NISLParameter1);

    return 0;

}

 

The OS is:

Linux version 4.15.0-65-generic

 

Compiler Version:

icc (ICC) 19.0.4.243 20190416

13 posts / 0 new

Does the test case NOT give SegFault with GCC?


Hello, this code can't be compiled

prog.cpp:6:19: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
     return strcmp(i, "none");
                   ^
In file included from prog.cpp:1:
/usr/include/string.h:136:32: note:   initializing argument 1 of ‘int strcmp(const char*, const char*)’
 extern int strcmp (const char *__s1, const char *__s2)
                    ~~~~~~~~~~~~^~~~

 


Quote:

Viet Hoang (Intel) wrote:

Does the test case NOT give SegFault with GCC?

Hello Viet:

     In GCC, it gives SegFault with or without -g/-O0 options. But in intelc, the behavior is inconsistent with or without -g/-O0 options. When there are no options at compile time, just like "icc testcase.c -o testcase", the run result is -1. After adding options -g/-O0 at compile time, just like "icc -g testcase.c -o testcase" the run result is SegFault. So I wonder if this is an optimization problem for the compiler icc. Sorry if I'm misunderstanding something.


Quote:

Vladimir Polin (Intel) wrote:

Hello, this code can't be compiled

prog.cpp:6:19: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
     return strcmp(i, "none");
                   ^
In file included from prog.cpp:1:
/usr/include/string.h:136:32: note:   initializing argument 1 of ‘int strcmp(const char*, const char*)’
 extern int strcmp (const char *__s1, const char *__s2)
                    ~~~~~~~~~~~~^~~~

 

Hello Vladimir:

      It seems that you compiled it with the icpc compiler. But the problem is with the c compiler ICC. ICC prints a warning but eventually compiles it successfully.


But first, you need to fix the call to strcmp(i, "none"); 


Quote:

Viet Hoang (Intel) wrote:

But first, you need to fix the call to strcmp(i, "none"); 

        ICC can certainly run as expected when the first parameter is fixed to be string instead of int. But, I think if I pass an unexpected type int to the first parameter of the strcmp(const char* s1, const char* s2), maybe it should give the SegFault instead of -1 because it doesn't make sense to compare int and string using strcmp.


I got your point. our nextgen compiler (19.1) gives a SegFault.

$ icc t.c -w -qnextgen -V&&./a.out

Intel(R) C Compiler for applications running on Intel(R) 64, Version 2021.1 NextGen Build 20191121
Segmentation fault (core dumped)


Quote:

qu, xing wrote:

        ICC can certainly run as expected when the first parameter is fixed to be string instead of int. But, I think if I pass an unexpected type int to the first parameter of the strcmp(const char* s1, const char* s2), maybe it should give the SegFault instead of -1 because it doesn't make sense to compare int and string using strcmp.

In C world it is called "undefined behaviour". You did not pass "int" you passed HEX(-4569) address of const char in your application. If your pointer (-4569) points to readable section it will compare the garbage to your "none" string. If this is non-readable section it segfaults. it is not only compiler, it is up to LD linker where to set sections. It looks for your release version there is readable "0" in the memory at HEX(-4569) address so you get -1.

In general - "garbage in -> garbage out".

Vladimir 


Quote:

Viet Hoang (Intel) wrote:

I got your point. our nextgen compiler (19.1) gives a SegFault.

$ icc t.c -w -qnextgen -V&&./a.out

Intel(R) C Compiler for applications running on Intel(R) 64, Version 2021.1 NextGen Build 20191121
Segmentation fault (core dumped)

That's good! Thanks for your reply.


Quote:

Vladimir Polin (Intel) wrote:

Quote:

qu, xing wrote:

 

        ICC can certainly run as expected when the first parameter is fixed to be string instead of int. But, I think if I pass an unexpected type int to the first parameter of the strcmp(const char* s1, const char* s2), maybe it should give the SegFault instead of -1 because it doesn't make sense to compare int and string using strcmp.

 

 

In C world it is called "undefined behaviour". You did not pass "int" you passed HEX(-4569) address of const char in your application. If your pointer (-4569) points to readable section it will compare the garbage to your "none" string. If this is non-readable section it segfaults. it is not only compiler, it is up to LD linker where to set sections. It looks for your release version there is readable "0" in the memory at HEX(-4569) address so you get -1.

In general - "garbage in -> garbage out".

Vladimir 

Thank you Vladimir for your detailed explanation! And how do you know the pointer(-4569) points to readable "0" instead of others?


The arbitrary value of the integer could resolve to a pointer anywhere within the range of the integer. The resultant address may or may not be an address that is or can be mapped to your process virtual address space. If not mapped, you get a segfault.If mapped, or becomes mapped, the strcmp has something to work with. When the assumed string at arbitrary virtual address is scanned, there is a potential that the partially matching scan crosses into a virtual address that is not mapped and not mapable (or is marked execute only), and in which case you get a segfault. However, should the attempted match succeed (unlikely) or fail (see string termination 0), then the appropriate result is returned. "garbage in -> garbage out".

Please use error and warning checking for arguments on function calls, and correct the errors in your program. Do not expect undefined behavior to produce expected and/or same results.

Jim Dempsey


Quote:

qu, xing wrote:

Thank you Vladimir for your detailed explanation! And how do you know the pointer(-4569) points to readable "0" instead of others?

you can try to play with following code.

#include <string.h>
#include <stdio.h>

int has_8bit(int i)
{
    return strcmp((char*)i, "none");
}
int main(void){
    int *NISLParameter0 = -4569;
    printf("%d\n",*NISLParameter0);
    printf("%s\n",(char*)*NISLParameter0);
    int NISLParameter1 = has_8bit(*NISLParameter0);
    printf("%d\n",NISLParameter1);
    return 0;
}

 

Leave a Comment

Please sign in to add a comment. Not a member? Join today