Regexc - Segmentation Fault - c

I'm relatively new to C and I have a problem with the following:
regex_t re;
regmatch_t matches[2];
int start;
int end;
int count = 0;
int reti = regcomp(&re, "^(?:[a-zA-Z]|[a-zA-Z](?:[a-zA-Z0-9\\-])*[a-zA-Z0-9])(?:\\.(?:[a-zA-Z]|[a-zA-Z](?:[a-zA-Z0-9\\-])*[a-zA-Z0-9]))*$", REG_EXTENDED);
while (1) {
printf("Local = %s\n", local);
reti = regexec(&re, local, 2, matches, 0);
// More code here
}
When I run this, I get a segmentation fault.
local was defined as char *local and is being printed out correctly.
I ran the code using GDB and it turns out the issue is arising at the line:
reti = regexec(&re, local, 2, matches, 0);
I can't seem to figure out why.
This is the output from gdb:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7af8d42 in regexec () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) backtrace
#0 0x00007ffff7af8d42 in regexec () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x000000000040092d in email_in (str=0x400aa8 "giri#gmail.com") attestdriver.c:70
#2 0x0000000000400780 in main () at testdriver.c:15
Would anyone have any ideas as to what might be the issue?
Thanks for your help.

The problem is actually here:
int reti = regcomp(&re, "^(?:[a............
From here:
You need to check the return of regcomp, it will tell you that your regex is invalid.
You will get Invalid preceding regular expression
(?: is not supported by POSIX regexes.
It's throwing this error because:
A common way to get a segfault is to dereference a null pointer
(From here)
The regex cannot initialize because of the illegal (?:
The original error is shown in the return of regcomp, and does not halt execution.

Related

gdb debugging segmentation fault, arguments count showing false

I am trying to debug the segmentation fault of a menu program written in 'C' and the main function is shown in the below screen shot.
int main( int ac, char **av ) {
/* TDT,II - 02 May 2006 - Added this check to see if there is a Debug level passed in */
if ( ac > 0 ) {
iDebug = atoi( av[1] );
sprintf( cLogText, "Setting Debug Level to ~%d~", iDebug );
WriteTrace( cLogText );
};
initscr();
clear();
t1=time(NULL);
local =localtime(&t1);
Svc_Login();
for ( ; ; ) {
cases_on_pc=FALSE;
if ( !Process_security() ) break;
menu1();
};
wrap_up(0);
endwin( );
exit(0);
}
when i try to debug (run using gdb), without any arguments, getting halted at 0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6 as shown below. if(ac>0) becomes true, only when i pass any arguments. but i haven't passed any runtime arguments. still that 'f block is being executed and function atoi(av[1]) is called and resulted in segmentation fault. I am unable to figure it out. how to proceed further to identify and correct the issue so that i could run the menu program successfully. could somebody give any suggestions on this?
-rw-rw-r--. 1 MaheshRedhat MaheshRedhat 2275270 Jan 10 03:09 caomenu.c
-rw-rw-r--. 1 MaheshRedhat MaheshRedhat 0 Jan 10 03:09 caomenu.lis
-rwxr-xr-x. 1 root root 796104 Jan 10 03:10 scrmenu
[MaheshRedhat#azureRHEL MenuPrograms]$
[MaheshRedhat#azureRHEL MenuPrograms]$ gdb ./scrmenu
(gdb) run
Starting program: /home/MaheshRedhat/MenuPrograms/scrmenu
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-189.5.0.1.el8_6.x86_64 libnsl-2.28-189.5.0.1.el8_6.x86_64 ncurses-libs-6.1-9.20180224.el8.x86_64
(gdb)
(gdb) bt
#0 0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6
#1 0x00007ffff34bfce4 in atoi () from /lib64/libc.so.6
#2 0x0000000000401674 in main (ac=1, av=0x7fffffffe228) at caomenu.pc:541
(gdb)
Update
The above issue has been resolved. Here is another encounter of segmentation fault.
from this backtrace of system calls, in WriteTrace (cEntryText=0x6f4d20 <cLogText> in my main function lead to call fputs() from library file /lib64/libc.so.6
Starting program: /home/MaheshRedhat/MenuPrograms/scrmenu 1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff34f7f5c in fputs () from /lib64/libc.so.6
(gdb)
(gdb) bt
#0 0x00007ffff34f7f5c in fputs () from /lib64/libc.so.6
#1 0x0000000000472efc in WriteTrace (cEntryText=0x6f4d20 <cLogText> "Setting Debug Level to ~1~") at caomenu.pc:18394
#2 0x00000000004016a0 in main (ac=2, av=0x7fffffffe208) at caomenu.pc:543
(gdb)
The below is the declaration of cLogText
char cLogText[250];
The below is code for WriteTrace:
/**************************************************************************
routine to write an entry in the trace file
**************************************************************************/
void WriteTrace( char *cEntryText ) {
char cTimeStamp[40]; /* time stamp variable */
char cTimeFormat[]="%H:%M:%S: "; /* time stamp format */
GetTimeStamp( &cTimeStamp[0], sizeof(cTimeStamp), &cTimeFormat[0] );
TrcFile = fopen( cTraceFile, cTrcOpenFlag ); /* open the file */
cTrcOpenFlag[0] = 'a'; /* after first, always app} */
fprintf(TrcFile, "%s", cTimeStamp); /* write the time stamp */
fprintf(TrcFile, "%s\n", cEntryText); /* write the entry */
fclose(TrcFile); /* close the trace file */
return; /* return to caller */
}
From C11:
The value of argc shall be nonnegative. argv[argc] shall be a null
pointer. If the value of argc is greater than zero, the array members
argv[0] through argv[argc-1] inclusive shall contain pointers to
strings, which are given implementation-defined values by the host
environment prior to program startup. The intent is to supply to the
program information determined prior to program startup from elsewhere
in the hosted environment. If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the
implementation shall ensure that the strings are received in
lowercase.
If the value of argc is greater than zero, the string
pointed to by argv[0] represents the program name; argv[0][0] shall be
the null character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the program
parameters.
The condition
( ac > 0 )
would be true even if you provided 0 program arguments, with argv[0] pointing to the program name (if it was available).
This statement:
atoi( av[1] );
tries to access av[1] which the Standard defines to be NULL when no program arguments were provided. Hence the segmentation violation signal.
fopen returns NULL to indicate failure.
TrcFile = fopen( cTraceFile, cTrcOpenFlag );
You do not check its return value here, before passing it to fprintf.
Perhaps:
TrcFile = fopen( cTraceFile, cTrcOpenFlag );
if (!TrcFile) {
deal with error here..
}
if (ac > 0) {
iDebug = atoi(av[1]); // out of bounds here, when you run `./scrmenu`
}
when you run ./scrmenu, you will have ac=1 and av[0]=./scrmenu
You may misunderstand ac and av mean in the main function.
how to fix:
if (ac == 2) {
iDebug = atoi(av[1]); // parse the second argument
}
then you can run: ./scrmenu or ./scrmenu 1 something like this.
you can check this post about command line argument

Segmentation fault

#include <stdio.h>
int main(void)
{
/* an array with 5 rows and 2 columns*/
char* a[5][2];
int y, p;
for(y = 0; y < 5; y++)
{
for(p = 0; p < 2; p++)
{
scanf("%s", a[y][p]);
}
}
int i, j;
/* output each array element's value */
for ( i = 0; i < 5; i++ )
{
for ( j = 0; j < 2; j++ )
{
printf("a[%d][%d] = %s\n", i,j, a[i][j] );
}
}
return 0;
}
I've been getting a Segmentation fault as an output of this program after inserting 2 strings. Can anyone tell me what's wrong with my code?
Problem:
You're declaring 10 uninitialized pointers here:
char* a[5][2];
And then trying to fill them with data:
scanf("%s", a[y][p]);
This is wrong. You need to allocate memory before copying data.
Solution:
I would do this in a more sexy way, but the quick solution would be:
#define MAX_LEN 100
char a[5][2][MAX_LEN];
/* ... */
scanf("%s", a[y][p][0]);
Just a hint on helping troubleshoot. Hope this will help the future readers who are new to pointers.
A better way to troubleshoot a segmentation fault is to run it with a debugger like gdb.
e.g
Compile your program with gdb (You need gdb installed on your host)
gcc -ggdb Test.c -o Test
Then run it with gdb
gdb ./Test
In your case, you will see an output like this. It'll go to the gdb prompt.
Then type run or r, it will run the program. Then it asks for an input. Type your input value. Then the segmentation fault occurs. Now you can see your backtrace by typing backtrace or bt. You can see which line causes your crash. You can see the code by list. You can go to any line by typeing list <line>. Go through a GDB Guide to find out more commands.
It tries to access a pointer, probably invalid that's why it crashes. Then find out why it's invalid. Probably you didn't initialize it or didn't allocate memory. So the easiest fix would be to declare it as an array (rather than a pointer array) like #Andrewjs mentioned in his answer.
Reading symbols from /tmp/Examples/Test...done.
(gdb) run
Starting program: /tmp/Examples/Test
for 1
for 2
10
Program received signal SIGSEGV, Segmentation fault.
0x005c5c3d in _IO_vfscanf_internal (s=0x6d1420, format=0x804867e "%s", argptr=0xbfffe984 "\020\204\004\b", errp=0x0) at vfscanf.c:840
840 *str++ = c;
(gdb) backtrace
#0 0x005c5c3d in _IO_vfscanf_internal (s=0x6d1420, format=0x804867e "%s", argptr=0xbfffe984 "\020\204\004\b", errp=0x0) at vfscanf.c:840
#1 0x005cebbb in __scanf (format=0x804867e "%s") at scanf.c:35
#2 0x0804850d in main () at Test.c:16 <-- Your program's last call
(gdb) list
835 }
836 #else
837 /* This is easy. */
838 if (!(flags & SUPPRESS))
839 {
840 *str++ = c; <-- Crash point
841 if ((flags & MALLOC)
842 && (char *) str == *strptr + strsize)
843 {
844 /* Enlarge the buffer. */
(gdb)
For advance debugging of applications This may help

Random seeding seg fault

I am asked to put a random seeding into a program that is called when a user types in -r. It is shown to look like
-r1234567
So as a global variable I set Random = 1234567.
I added this to the top of my function as well:
printf("Seed: %d\n", Random);
srand48(Random);
Every time I use -r1234567 My program segfaults and says this:
Program received signal SIGSEGV, Segmentation fault.
____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7ad8020) at ../stdlib/strtol_l.c:298
298 ../stdlib/strtol_l.c: No such file or directory.
(gdb) bt
#0 ____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7ad8020) at ../stdlib/strtol_l.c:298
#1 0x00007ffff77589e0 in atoi (nptr=<optimized out>) at atoi.c:28
#2 0x0000000000401d8c in getCommandLine (argc=6, argv=0x7fffffffe238)
at prog.c:171
#3 0x0000000000401514 in main (argc=6, argv=0x7fffffffe238) at prog.c:35
(gdb) up
#1 0x00007ffff77589e0 in atoi (nptr=<optimized out>) at atoi.c:28
28 atoi.c: No such file or directory.
(gdb) up
#2 0x0000000000401d8c in getCommandLine (argc=6, argv=0x7fffffffe238)
at prog.c:171
warning: Source file is more recent than executable.
In my command like: the case looks like this:
while ((c = getopt(argc, argv, "g:n:a:h:s:d:v:r")) != -1)
case 'r': Random = atoi(optarg); break;
So a user wants to to randomize using a seed. They do ./program -r1234567. This then goes into the two lines of code that I put above and should randomize.
Any suggestions?
Your problem is the getopt call, in that you forgot to tell getopt that the -r argument takes a value:
getopt(argc, argv, "g:n:a:h:s:d:v:r:")
/* ^ */
/* | */
/* Add colon here */
Because of that, the optarg pointer is NULL when you call atoi.
you are giving -r1234567 from the command line , How you are parsing it and giving ito atoi ?
if atoi get "1234567" as its argument then there should not be any problem .. Can you paste the logic which parses the argv[1] ?
Are declaring Random as an int?. srand48 takes a long as an argument so you should be usuing atol instead of atoi:
long Random = 42;
printf("Seed: %d\n", Random);
srand48(Random);
The problem is .. you are missing ":" at the end of argument r ...because of this NULL is being passed to atoi .. try adding ":" at the end of r in the getopt !!

segmentation fault on printing a returned value of a function

Whenever i try to do:
char buffed[1024];
snprintf(buffed, sizeof(buffed), "bash.sh %s &", get_value("request-uri"));
system(buffed);
this is the function I use:
char *get_value(char *name) {
FORMAT_NODE *node;
#ifdef DEBUG
ASSERT(name);
#endif
if (strlen(name) == 0)
return EMPTY_FIELD;
if ((node = get_field(name))) {
return node->value;
} else {
return EMPTY_FIELD;
}
}
Compiling is okay but whenever it should print the value it gives a segmentation fault and crashes, can someone explain me what I am doing wrong?
Thanks in advance!
edit:
get_value("request-uri") is the one im talking about and it should be a string
strstr(get_value("request-uri"), "index.php") works perfectly!
but "index.php" should come from get_value
edit2:
gdb:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff73f3321 in __strlen_sse2 () from /lib64/libc.so.6
The problem here was solved by CBIII for telling me to use gdb, the value was empty because it flushed before it was used.
get_value("request-uri") returned 0x0

Heap corruption in HP-UX?

I'm trying to understand what's going wrong with a program run in HP-UX 11.11 that results in a SIGSEGV (11, segmentation fault):
(gdb) bt
#0 0x737390e8 in _sigfillset+0x618 () from /usr/lib/libc.2
#1 0x73736a8c in _sscanf+0x55c () from /usr/lib/libc.2
#2 0x7373c23c in malloc+0x18c () from /usr/lib/libc.2
#3 0x7379e3f8 in _findbuf+0x138 () from /usr/lib/libc.2
#4 0x7379c9f4 in _filbuf+0x34 () from /usr/lib/libc.2
#5 0x7379c604 in __fgets_unlocked+0x84 () from /usr/lib/libc.2
#6 0x7379c7fc in fgets+0xbc () from /usr/lib/libc.2
#7 0x7378ecec in __nsw_getoneconfig+0xf4 () from /usr/lib/libc.2
#8 0x7378f8b8 in __nsw_getconfig+0x150 () from /usr/lib/libc.2
#9 0x737903a8 in __thread_cond_init_default+0x100 () from /usr/lib/libc.2
#10 0x737909a0 in nss_search+0x80 () from /usr/lib/libc.2
#11 0x736e7320 in __gethostbyname_r+0x140 () from /usr/lib/libc.2
#12 0x736e74bc in gethostbyname+0x94 () from /usr/lib/libc.2
#13 0x11780 in dnetResolveName (name=0x400080d8 "smtp.org.com", hent=0x737f3334) at src/dnet.c:64
..
The problem seems to be occurring somewhere inside libc! A system call trace ends with:
Connecting to server smtp.org.com on port 25
write(1, "C o n n e c t i n g t o s e ".., 51) .......................... = 51
open("/etc/nsswitch.conf", O_RDONLY, 0666) ............................... [entry]
open("/etc/nsswitch.conf", O_RDONLY, 0666) ................................... = 5
Received signal 11, SIGSEGV, in user mode, [SIG_DFL], partial siginfo
Siginfo: si_code: I_NONEXIST, faulting address: 0x400118fc, si_errno: 0
PC: 0xc01980eb, instruction: 0x0d3f1280
exit(11) [implicit] ............................ WIFSIGNALED(SIGSEGV)|WCOREDUMP
Last instruction by the program:
struct hostent *him;
him = gethostbyname(name); // name == "smtp.org.com" as shown by gdb
Is this a problem with the system, or am I missing something?
Any guidance for digging deeper would be appreciated.
Thx.
Long story short: vsnprintf corrupted my heap under HP-UX 11.11.
vsnprintf was introduced in C99 (ISO/IEC 9899:1999) and "is equivalent to snprintf, with the variable argument list" (§7.19.6.12.2), snprintf (§7.19.6.5.2): "If n is zero, nothing is written".
Well, HP UX 11.11 doesn't comply with this specification. When 2nd arg == 0, arguments are written at the end of the 1st arg.. which, of course, corrupts the heap (I allocate no space when maxsize==0, given that nothing should be written).
HP manual pages are unclear ("It is the user's responsibility to ensure that enough storage is available."), nothing is said regarding the case of maxsize==0. Nice trap.. at the very least, the WARNINGS section of the man page should warn std-compliant users..
It's an egg/chicken pb: vnsprintf is variadic, so for the "user's responsibility" to ensure that enough storage is available" the "user's responsibility" must first know how much space is needed. And the best way to do that is to call vnsprintf with 2nd arg == 0: it should then return the amount of space required and sprintfs nothing.. well, except HP's !
One solution to use vnsprintf under this std violation to determine needed space: malloc 1 byte more to your buffer (1st arg) and call vnsprintf(buf+buf.length,1,..). This only puts a \0 in the new byte you allocated. Silly, but effective. If you're under wchar conditions, malloc(sizeof..).
Anyway, workaround is trivial : never call v/snprintf under HP-UX with maxsize==0!
I now have a happy stable program!
Thanks to all contributers.
Heap corruption through vsnprintf under HP-UX B11.11
This program prints "##" under Linux/Cygwin/..
It prints "#fooo#" under HP-UX B11.11:
#include <stdarg.h>
#include <stdio.h>
const int S=2;
void f (const char *fmt, ...) {
va_list ap;
int actualLen=0;
char buf[S];
bzero(buf, S);
va_start(ap, fmt);
actualLen = vsnprintf(buf, 0, fmt, ap);
va_end(ap);
printf("#%s#\n", buf);
}
int main () {
f("%s", "fooo");
return 0;
}
Whenever this situation happens to me (unexpected segfault in a system lib), it is usually because I did something foolish somewhere else, i.e. buffer overrun, double delete on a pointer, etc.
In those instances where my mistake is not obvious, I use valgrind. Something like the following is usually sufficient:
valgrind -v --leak-check=yes --show-reachable=yes ./myprog
I assume valgrind may be used in HP-UX...
Your stack trace is in malloc which almost certainly means that somewhere you corrupted one of malloc's data structures. As a previous answer said, you likely have a buffer overrun or underrun and corrupted one of the items allocated off the heap.
Another explanation is that you tried to do a free on something that didn't come from the heap, but that's less likely--that would probably have crashed right in free.
Reading the (OS X) manpage says that gethostbyname() returns a pointer, but as far as I can tell may not be allocating memory for that pointer. Do you need to malloc() first? Try this:
struct hostent *him = malloc(sizeof(struct hostent));
him = gethostbyname(name);
...
free(him);
Does that work any better?
EDIT: I tested this and it's probably wrong. Granted I used the bare string "stmp.org.com" instead of a variable, but both versions (with and without malloc()ing) worked on OS X. Maybe HP-UX is different.

Resources