I used GDB, and realised that the problem was reaching these line of codes:
in main:
'''
else if(strcmp("insert",arg[1])==0){
insert("a.txt","Cem","Mec","Cem","-a");
}
'''
insert method:
'''
void insert(char *filename, char *insertedWord, char *searchedWord,char *oldsearchedWord, char *ab){
if(strcmp("-a",ab) == 0){
strcat(searchedWord," ");
strcat(searchedWord, insertedWord);
replace(filename,searchedWord,oldsearchedWord);
}
else if(strcmp("-b",ab) == 0){
strcat(insertedWord," ");
strcat(insertedWord, searchedWord);
replace(filename,insertedWord,oldsearchedWord);
}
}
'''
and the error is:
Program received signal SIGSEGV, Segmentation fault.
__strcmp_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:32
32 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or directory.
I checked my replace method. It works.
You are trying to strcat using a string literal as target. You are not allowed to do this because string literals are usually placed on read only data segments and attempting to modify them is undefined behaviour.
switch to
char insertedWord[256] = "cem";
char searchedWord[256] = "mec";
...
and then pass those (modfiable) arrays instead.
Related
Heres my main.c:
int main() {
char *x = "add r3,r5";
char *t;
char **end;
t = getFirstTok(x,end);
printf("%s",t);
}
And the function getFirstTok:
/* getFirstTok function returns a pointer to the start of the first token. */
/* Also makes *endOfTok (if it's not NULL) to point at the last char after the token. */
char *getFirstTok(char *str, char **endOfTok)
{
char *tokStart = str;
char *tokEnd = NULL;
/* Trim the start */
trimLeftStr(&tokStart);
/* Find the end of the first word */
tokEnd = tokStart;
while (*tokEnd != '\0' && !isspace(*tokEnd))
{
tokEnd++;
}
/* Add \0 at the end if needed */
if (*tokEnd != '\0')
{
*tokEnd = '\0';
tokEnd++;
}
/* Make *endOfTok (if it's not NULL) to point at the last char after the token */
if (endOfTok)
{
*endOfTok = tokEnd;
}
return tokStart;
}
Why do i get segmentation fault running this main program?
I'm programming a two pass aseembler and i need a function that get parse a string by a delimiter, In this case a white space. Is it better to use strtok instead for this purpose?
I need a command pasrer - So that it will extract "add", an operand parser (By , delimiter), To extract "r3" and "r5". I wanted to check if this getFirstTok function is good for this purpose but when i try to run it i get a segmentation fault:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Thank you.
As pointed out in the comments, string literals are read-only, as they are baked into the compiled program. If you don't want to go with the suggested solution of making your "source program" a stack-allocated array of characters (char x[] = "add r3,r5"), you can use a function like strdup(3) to make a readable/writable copy like so:
#include <string.h>
[...]
char *rw_code = strdup(x);
t = getFirstTok(rw_code, end);
printf("%s", t);
free(rw_code); /* NOTE: invalidates _all_ references pointing at it! */
[...]
And as a little aside, I always make string literals constant const char *lit = "...", as the compiler will usually warn me if I attempt to write to them later on.
I'm working in C, Linux terminal. I need to find a pattern in a text and recolor it. GDB debugging can locate the function that is causing the problem via (gdb) backtrace, but it shows me a terrible message when I try to find the exact line:
Error
Program received signal SIGSEGV, Segmentation fault.
strstr_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S:40
40 ../sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S: No such file or dir
ectory.
(gbd)
The broken function is find_and_recolor:
char* my_replace(char *text, char* replacement)
{
int lgreplacement = strlen(replacement);
int lgtext = strlen(text);
char *aux = (char*)malloc((lgreplacement + lgtext + 10) * sizeof(char));
strcpy(aux, replacement);
strcat(aux, text);
return(aux);
}
char* find_and_recolor(char* text, char* pattern)
{
int lgpattern = strlen(pattern);
int lgreplace = lgpattern + 10;//there are exactly 10 characters that must be inserted along the pattern word
int dif = 0;
char *p;
char *replacement = (char*)malloc(lgreplace * sizeof(char));
strcpy(replacement, "\e[0;31m");
strcat(replacement, pattern);
strcat(replacement, "\e[m");//to recolor a word in red, that word must be surrounded by those characters
while(p = strstr(text + dif, pattern))
{
p = my_replace(p, replacement);
p += lgreplace;
dif = p - text;
}
free(replacement);
return strdup(text);
}
it shows me a terrible message when I try to find the exact line:
There is nothing terrible, weird or unusual about this message, you just need to learn proper debugging technique.
What's happening is that the segmentation fault doesn't happen in your code, it happens inside GLIBC code (inside strstr), because you called strstr with bad arguments.
To find which call to strstr that was, use GDB up command to step out of GLIBC code, and into your code. Once you are inside find_and_recolor, you would be able to see the exact line, and print values of text, dif and pattern which caused your crash (assuming you compiled your code for debugging, i.e. with the -g flag).
Updating diff to p-text in while loop where both pointer points to different array doesn't make sense. It is undefined behavior.
Also code has other issues.
Uninitialized variable.
Less optimized as number of call can be reduced.
I am using this library for libgps and having a few issues with it getting it to run properly.
The error from my debugger after it says segfault is:
Cannot find bounds of current function
The line of code throwing this is located in this file, on line 132.
uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16);
I don't know the context of this at all, and I dont know why it would / wouldn't throw a segfault.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <gps.h>
#include <math.h>
/*
*
*/
int main(int argc, char** argv) {
// Open
gps_init();
gps_on();
loc_t data;
gps_location(&data);
printf("%lf %lf\n", data.latitude, data.longitude);
return (EXIT_SUCCESS);
}
The function gps_location() takes you into gps.c and from there it runs into serial.c, once it runs:
void serial_readln(char *buffer, int len)
{
char c;
char *b = buffer;
int rx_length = -1;
while(1) {
rx_length = read(uart0_filestream, (void*)(&c), 1);
if (rx_length <= 0) {
//wait for messages
sleep(1);
} else {
if (c == '\n') {
*b++ = '\0';
break;
}
*b++ = c;
}
}
}
On the break it returns to gps.c goes into:
switch (nmea_get_message_type(buffer)) {
which takes it into nmea.c for nmea_get_message_type above.
It then runs the line:
if ((checksum = nmea_valid_checksum(message)) != _EMPTY)
taking it down to: uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16); which is where the error is.
What is causing this?
Edit:
uint8_t is defined as: typedef unsigned char uint8_t;
Segmentation fault is not a "thrown exception" per se, it is a hardware-issued problem ("you said go there, but I don't see anything named 'there'").
As for your problem: what happens when strchr() does not find the specified character? I suggest you try it and find out.
The code you are working with is horrible and has no error checking anywhere. So it may go haywire for any unexpected input. This could be a potential security vulnerability too.
To fix this particular instance, change the code to:
if ( !message )
return NMEA_CHECKSUM_ERR; // possibly `exit` or something, this shouldn't happen
char *star = strchr(message, '*');
if ( !star )
return NMEA_CHECKSUM_ERR;
uint8_t checksum = strtol(star, NULL, 16);
The nmea_parse_gpgga and nmea_parse_gprmc also have multiple instances of a similar problem.
These functions might be acceptable if there was a parser or a regexp check that sanitizes the input before calling these functions. However, based on your question (I didn't check the codebase), it seems data is passed directly from read which is inexcusable.
The segfaulting function was not designed to handle an empty message or in fact any message not matching the expected form.
Another disastrous blunder is that the serial_readln function never checks that it does not write beyond len.
This question already has answers here:
Bad permissions for mapped region [duplicate]
(2 answers)
Closed 9 years ago.
My function should print out letters which are more than once in string. I have no idea why I get an empty output, or my program 'stops working'.
#include <string.h>
#include <stdio.h>
void funkcja3 (char []);
int main()
{
funkcja3("napnapnaaw");
return 0;
}
void funkcja3 (char napis[])
{
int i=0,j;
for(;i<strlen(napis);i++)
{
if((napis[i]>='a')&&(napis[i]<='z'))
{
int n=0;
for(j=i+1;j<strlen(napis);j++)
{
if(napis[i]==napis[j])
{
n++;
napis[j]=' ';
}
}
if(n>0)
{
printf("%c ", napis[i]);
}
}
}
}
You need to pass a modifiable string:
int main()
{
char str[] = "napnapnaaw";
funkcja3(str);
return 0;
}
This is not a direct answer to your question, but if you just want to print out all the non-capital letters that appear more than once in a given string, then you can just use a histogram (symbol-counting) instead:
void funkcja3(char napis[])
{
int histogram['z'-'a'+1] = {0};
for (int i=0; napis[i]!=0; i++)
{
if ('a' <= napis[i] && napis[i] <= 'z')
histogram[napis[i]-'a']++;
}
for (int i=0; i<'z'-'a'+1; i++)
{
if (histogram[i] > 1)
printf("%c ",'a'+i);
}
}
BTW, histogram = the number of occurrences of each symbol in the data.
When I run your program on my machine (Ubuntu, gcc 4.6), I get a segmentation fault and a core dump. Giving the program and the core dump to gdb and doing a backtrace gives
$ gdb a.out core
Core was generated by `/tmp/a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004005a2 in funkcja3 (napis=0x40072c "napnapnaaw") at a.c:25
25 napis[j]=' ';
(gdb) bt
bt
#0 0x00000000004005a2 in funkcja3 (napis=0x40072c "napnapnaaw") at a.c:25
#1 0x0000000000400520 in main () at a.c:8
This hint brings me to removing line 25 and running the program again
$ a.out
n a p n a a
which shows all characters, which were repeated somewhere later in the string.
When you call funkcja3, you're calling it with a string literal. This string literal is at a memory location that isn't modifiable, so the call to napid[j] = ' ' should fail (and does so when I copy your example in to visual studio 2013). What you need to do is either A: use std::string (or another string implementation) or B: make a copy of the string in the function, examine it, and then delete the copy when done. Either way, you probably shouldn't be modifying the original string going in to the function. It's generally bad practice to modify objects passed in to a function unless the function absolutely has to do so.
There are some other ways of completing this task as well, such as an array of 26 shorts to hold the counts for each character. Make those counts and then print out any character that has more then 1.
I keep getting this error and I am not sure how it applies to my program. This is my program.
#include<stdio.h>
#include<stdlib.h>
int nextword(char *str);
void main(void)
{
char *str = "Hello! Today is a beautiful day!!\t\n";
int i = nextword(str);
while(i != -1)
{
printf("%s\n",&(str[i]));
i = nextword(NULL);
}
}
int nextword(char *str)
{
// create two static variables - these stay around across calls
static char *s;
static int nextindex;
int thisindex;
// reset the static variables
if (str != NULL)
{
s = str;
thisindex = 0;
// TODO: advance this index past any leading spaces
while (s[thisindex]=='\n' || s[thisindex]=='\t' || s[thisindex]==' ' )
thisindex++;
}
else
{
// set the return value to be the nextindex
thisindex = nextindex;
}
// if we aren't done with the string...
if (thisindex != -1)
{
nextindex = thisindex;
// TODO: two things
// 1: place a '\0' after the current word
// 2: advance nextindex to the beginning
// of the next word
while (s[nextindex] != ' ' || s[nextindex] != '\n' || s[nextindex] != '\t')
{
if ( s[nextindex] == '\0')
return -1;
else
{
nextindex++;
if (s[nextindex]==' '||s[nextindex]=='\n'||s[nextindex]=='\t')
str[nextindex]='\0';
}
}
}
return thisindex;
}
My program is supposed to have an output to the console of
Hello!
Today
is
a
beautiful
day!!
You are trying to change a String literal. This results in undefined behavior, such as a segfault.
str[nextindex]='\0'
and in Here, str is the parameter of nextWord(), which is:
char *str = "Hello! Today is a beautiful day!!\t\n";
int i = nextword(str);
Since "Hello! Today is a beautiful day!!\t\n" is a string literal - changing it is udnefined behavior, and in your case (luckily) it caused a seg-fault.
You should compile with all warnings and debugging info enabled (if using GCC e.g. on Linux, that means compiling with gcc -Wall -g).
Then you should learn how to use the debugger (i.e. gdb on Linux) and possibly a leak detector like valgrind
a segmentation fault may happen if you dereference some "bad" pointer, e.g. a NULL one or an uninitialized one. It also may happen if you write into a read-only segment (you are probably overwriting a string literal which is put into a read-only -so called .text or .rodata- segment)
Taking account of every warning of the compiler (and enabling them) and using a debugger are essential skills of any C programmer.
Please give nextindex a initial value