- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Tags:
- CC++
- Development Tools
- Intel® C++ Compiler
- Intel® Parallel Studio XE
- Intel® System Studio
- Optimization
- Parallel Computing
- Vectorization
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does the test case NOT give SegFault with GCC?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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) ~~~~~~~~~~~~^~~~
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But first, you need to fix the call to strcmp(i, "none");
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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; }

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page