C KERN_INVALID_ADDRESS in regnexec() - c

I am Writing a program in c that relies heavily on regular expressions and my mechanism for executing them works 99% of the time but then it crashes the program every once in a while and I am stumped to why it would be.
New_Sifter() takes a String representation of its regex and a processing function that takes an array or strings and returns a single string.
Sifter* New_Sifter(const char* exp, const char*(*func)(const char**, size_t)){
Sifter *sifter = malloc(sizeof(Sifter*));
sifter->strRegEx = exp;
if(regcomp(&(sifter->regEx), exp, REG_EXTENDED)){
printf("Could not compile regular expression\n");
exit(1);
}
sifter->Sift = &Base_;
sifter->Custom = func;
sifter->nGroups = sifter->regEx.re_nsub + 1;
sifter->captures = malloc(sifter->nGroups * sizeof(regmatch_t));
Register_Disposable(sifter->captures); //stores pointer in registry to be freed later
Register_Disposable(sifter); //stores pointer in registry to be freed later
return sifter;
}
const char* Base_(Sifter* self, const char* source){
if(regexec(&(self->regEx), source, self->nGroups, self->captures,
REG_EXTENDED) != 0){
printf("about to return null\n");
return NULL;
}
return self->Custom(
//Sift_() returns an array of the strings captured in the regexec
Sift_(source, self->captures, self->nGroups), self->nGroups);
}
The error I get sometimes when I run this (and debug some with gdb) looks like:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x00007fff90d72b9f in tre_reset_last_matched_branches ()
(gdb) bt
0x00007fff90d72b9f in tre_reset_last_matched_branches ()
0x00007fff90d72a58 in tre_fill_pmatch ()
0x00007fff90d72e56 in tre_match ()
0x00007fff90d72d35 in regnexec ()
0x00000001000030cf in Base_ (self=0x1001000e0, source=0x1000033ee "add 11111, 22222, 33333")

Sifter *sifter = malloc(sizeof(Sifter*));
This line has one * too many. You are allocating space for a pointer, not space for the struct. Take the * out of the sizeof.

Related

c will a const *char function memory leak? [duplicate]

I am using json-c library to send json-object to client.And I notice there is no native function to release the memory which json_object_to_json_string allocate.Does the library release it automaticlly? OR I have to "free(str)" to avoid memory leak?
I tried to read its source code but it makes me unconscious...So anybody know this?
It seems that you don't need to free it manually.
I see that this buffer comes from within the json_object (see the last line of this function):
const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
{
if (!jso)
return "null";
if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
return NULL;
printbuf_reset(jso->_pb);
if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
return NULL;
return jso->_pb->buf;
}
The delete function frees this buffer:
static void json_object_generic_delete(struct json_object* jso)
{
#ifdef REFCOUNT_DEBUG
MC_DEBUG("json_object_delete_%s: %p\n",
json_type_to_name(jso->o_type), jso);
lh_table_delete(json_object_table, jso);
#endif /* REFCOUNT_DEBUG */
printbuf_free(jso->_pb);
free(jso);
}
It is important to understand that this buffer is only valid while the object is valid. If the object reaches 0 reference count, the string is also freed and if you are using it after it is freed the results are unpredictable.

Segmentation fault 11 in following code. How to avoid overflow?

void main(int argc, char* argv[]) {
char* hostname = (char*)malloc(sizeof(char)*1024);
hostname = getClientHostName("122.205.26.34");
printf("%s\n", hostname);
free(hostname);
}
char* getClientHostName(char* client_ip) {
char hostnames[5][2];
hostnames[0][0] = "122.205.26.34";
hostnames[0][1] = "aaaaa";
hostnames[1][0] = "120.205.36.30";
hostnames[1][1] = "bbbbb";
hostnames[2][0] = "120.205.16.36";
hostnames[2][1] = "ccccc";
hostnames[3][0] = "149.205.36.46";
hostnames[3][1] = "dddddd";
hostnames[4][0] = "169.205.36.33";
hostnames[4][1] = "eeeeee";
for(int i = 0; i<5; i++) {
if(!strcmp(hostnames[i][0], client_ip))
return (char*)hostnames[i][1];
}
return NULL;
}
Beginner in C.
I am not sure if there would be a better way to implement what I am trying to implement. The code is self-explanatory. Is there any way that I can predefine the size of hostname, using some general size of IP addresses, to avoid seg fault? Is there a even better way where I don't have to hardcode the size?
After fixing the compiler errors and warnings you get:
const char* getClientHostName(const char* client_ip) {
const char * hostnames[5][2];
hostnames[0][0] = "122.205.26.34";
hostnames[0][1] = "aaaaa";
hostnames[1][0] = "120.205.36.30";
hostnames[1][1] = "bbbbb";
hostnames[2][0] = "120.205.16.36";
hostnames[2][1] = "ccccc";
hostnames[3][0] = "149.205.36.46";
hostnames[3][1] = "dddddd";
hostnames[4][0] = "169.205.36.33";
hostnames[4][1] = "eeeeee";
for(int i = 0; i<5; i++) {
if(!strcmp(hostnames[i][0], client_ip))
return hostnames[i][1];
}
return NULL;
}
int main(int argc, char* argv[]) {
const char * hostname = getClientHostName("128.205.36.34");
printf("%s\n", hostname);
}
Is there a even better way where I don't have to hardcode the size?
Take the habit to compile with all warnings and debug info: gcc -Wall -Wextra -g with GCC. Improve the code to get no warnings at all.
If you want to get genuine IP addresses, this is operating system specific (since standard C11 don't know about IP addresses; check by reading n1570). On Linux you would use name service routines such as getaddrinfo(3) & getnameinfo(3) or the obsolete gethostbyname(3).
If this is just an exercise without actual relationship to TCP/IP sockets (see tcp(7), ip(7), socket(7)) you could store the table in some global array:
struct myipentry_st {
const char* myip_hostname;
const char* myip_address;
};
then define a global array containing them, with the convention of terminating it by some {NULL, NULL} entry:
const struct myipentry_st mytable[] = {
{"aaaaa", "122.205.26.34"},
{"bbbb", "120.205.36.30"},
/// etc
{NULL, NULL} // end marker
};
You'll better have a global or static variable (not an automatic one sitting on the call stack) because you don't want to fill it on every call to your getClientHostName.
Then your lookup routine (inefficient, since in linear time) would be:
const char* getClientHostName(char* client_ip) {
for (const struct myipentry_st* ent = mytable;
ent->myip_hostname != NULL;
ent++)
// the if below is the only statement of the body of `for` loop
if (!strcmp(ent->myip_address, client_ip))
return ent->myip_hostname;
// this happens after the `for` when nothing was found
return NULL;
}
You could even declare that table as a heap allocated pointer:
const struct myipentry_st**mytable;
then use calloc to allocate it and read its data from some text file.
Read the documentation of every standard or external function that you are using. Don't forget to check against failure (e.g. of calloc, like here). Avoid memory leaks by appropriate calls to free. Use the debugger gdb and valgrind. Beware of undefined behavior.
In the real world, you would have perhaps thousands of entries and you would perform the lookup many times (perhaps millions of times, e.g. once per every HTTP request in a web server or client). Then choose a better data structure (hash table or red-black tree perhaps). Read some Introduction to Algorithms.
Add * to type definition char * hostnames[5][2]. This must be array of pointers, not simple chars. Another necessary change is strcpy instead of = in strcpy( hostname, getClientHostName("122.205.26.34") );.
PS: Always try to compile with 0 compiler warnings, not only 0 errors!

Can't free() a char*

void* password_cracker_thread(void* args) {
cracker_args* arg_struct = (cracker_args*) args;
md5hash* new_hash = malloc (sizeof(md5hash));
while(1)
{
char* password = fetch(arg_struct->in);
if(password == NULL )
{
deposit(arg_struct->out,NULL);
free(new_hash);
pthread_exit(NULL);
}
compute_hash(password,new_hash);
if(compare_hashes(new_hash,(md5hash**)arg_struct->hashes,arg_struct->num_hashes) != -1)
{
printf("VALID_PASS:%s \n",password);
deposit(arg_struct->out,password);
}else{
free(password);
}
}
}
This is a part of a program, where you get char* passwords from a ringbuffer, calculate md5 and compare them and push them into the next buffer if valid.
My problem is now, why can't I free those I don't need?
The whole program will stop if I try to and if I don't, I get memory leaks.
"You", and by this I mean your program, can only free() storage that was got from malloc()-and-friends, and only in the granularity it was got, and only once per chunk of storage.
In the code you show here, you're attempting to free() something got from fetch(). Since we can't see the definition of that function and you have not provided any documentation of it, our best guess is that
fetch() gives you a pointer to something other than a whole chunk
got from malloc()-et-al; and/or
some other part of the program not
shown here free()s the relevant chunk itself.

malloc of char* also change other char* variable

I'm programming atmega8535 using C. I want to save data into flash disk using ALFAT OEM module. But, I have problem because the data that I want to save change into other variable in the middle program (Data saving is success, but the data is wrong). It occurs after malloc. I already malloc the variable data. I'm using hyperterminal to debugging my program
This is my code. I only show that related
// Declare your global variables here
char* reply = NULL;
char* directory = NULL;
char* fileName = NULL;
char* getFileName = NULL;
void writeCommand(char* command){ //to give command to ALFAT
//not related
}
void readCommand(){ //to request reply from ALFAT
//related (because contains malloc and also change my variable) but I give another example
}
void get_ErrorCode(char errorCode[4]){ //to get errorCode from ALFAT's reply
//not related
}
void get_Version(){ //to know ALFAT's version
//not related
}
void mountUSB0(){ //to mount USB port 0
//not related
}
void mountUSB1(){ //to mount USB port 1
//not related
}
void get_fileName(){ //to get fileName from ALFAT's reply after N command
//not related
}
int check_File(char port[1]){ //to check whether file already exists or not
//related (because contains malloc and also change my variable) but I give another example
}
void separate_Directory(char* fullDir, char* data){ //to separate directory and fileName from fullDirectory "fullDir"
int i,j;
int numSlash = 0; //numberOfSlash
int curNumSlash = 0; //currentNumberOfSlash
//CHECK THE DATA BEFORE MALLOC
printf("1st GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
//count backslash '\'=0x5C
for (i=0;i<strlen(fullDir);i++){
if(fullDir[i]== 0x5C ) numSlash++;
}
//count number of char for directory
i=0;
curNumSlash = 0;
while (curNumSlash != numSlash){
if(fullDir[i]== 0x5C) curNumSlash++;
i++;
}
//i = number of char for directory
//number of char for filename = strlen(fullDir)-total char directory
do{
directory = (char *) malloc (i+1);
}while(directory==NULL);
do{
fileName = (char *) malloc (strlen(fullDir)-i+1);
}while(fileName==NULL);
//CHECK THE DATA AFTER MALLOC (ALREADY CHANGED)
printf("2nd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
//save into directory until last backslash
i=0;
curNumSlash = 0;
while (curNumSlash != numSlash){
if(fullDir[i]== 0x5C) curNumSlash++;
directory[i] = fullDir[i];
i++;
}
directory[i] = '\0';
//remaining fullDir into fileName
j=0;
while (i < strlen(fullDir)){
fileName[j] = fullDir[i];
i++;
j++;
}
fileName[j] = '\0';
//CHECK THE DATA AGAIN (CHANGED INTO directory)
printf("3rd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
printf("separate directory = %s, fileName = %s, fullDir = %s\n",directory,fileName,fullDir);
}
void writeData (char* data, char* fullDir, char port[1], char statFileHandler[16]){
//I omit that not related
printf("1)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory);
separate_Directory(fullDir,data);
printf("2)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory);
//omitted
}
void main(){
char* data;
char* fullDir = NULL;
char port[1]="";
char statFileHandler[16];
//omitted
while(1){
//omitted (also omit the mounting)
do{
data = (char *) malloc (strlen("meong")+1); //+1 utk \0
}while(data==NULL);
strcpy(data,"meong");
data[strlen("meong")] = '\0';
fullDir = (char *) malloc (strlen("\\f1\\nyan.txt")+1);
strcpy(fullDir,"\\f1\\nyan.txt");
fullDir[strlen("\\f1\\nyan.txt")] = '\0';
for(i=0;i<strlen("\\f1\\nyan.txt");i++){
fullDir[i] = toupper(fullDir[i]);
}
//omit some printf for debugging
printf("fullDir di main= %s\n",fullDir);
printf("data di main = %s\n",data);
printf("address data di main = %x\n",*data);
writeData (data, fullDir, port, statFileHandler);
break;
}
while(1){}
}
}
}
Check the GUNYUH part. The output in HyperTerminal:
1st GUNYUH data = meong, address data = 196, directory = , address directory = 0
2nd GUNYUH data = , addressdata = 196, directory = , address directory = 196
3rd GUNYUH data = \F1\, address data = 196, directory = \F1\, address directory = 196
my data in main is "meong".
1st GUNYUH before malloc, the data still "meong"
2nd GUNYUH after malloc, the data already changed
3rd GUNYUH after defined the directory, the data also changed. (Well because the address also same so it point to the same address)
why it changed?
Is it because lack of memory problem? But, when there's no enough heap memory, the malloc will return NULL so it never go out from the loop. I already experienced the lack of heap memory before and it did can't go out from the loop.
I have also experience overlapping like this. But it is because I didn't use malloc. (but I didn't check the address and go for static array but not enough memory so back into dynamic and found that it need malloc)
some help please?
This is not an answer but it is too big for comments.
You have the following bugs:
In four different printf lines you cause undefined behaviour by passing null pointer for %s. (the variable directory). After undefined behaviour has begun, all bets are off.
Printing a pointer with %x causes undefined behaviour. To print a pointer use %p and cast the pointer to (void *) .
You do *THING instead of THING in 3 different places, for printf
Don't cast malloc, the cast may be hiding an error message indicating a bug
On the line for(i=0;i<strlen("\\f1\\nyan.txt");i++){ , i is undeclared.
You failed to include stdio.h, stdlib.h string.h and ctype.h .
There are two more } than { in your code.
After the line with fullDir = (char *) malloc... , you do not check to see whether malloc failed.
This code should not compile. This leads me to believe that you are not posting your real code. It is important that you post exactly the code that is failing.
You need to create a minimal program, test that that program still shows the problem, and post the code of that program unaltered.
This is because there could be problems that are in the "real code" but not in the code you posted. Since you don't know where the problem is, you can't be sure that you have included the part that causes the problem.
In fact, if I fix all the bugs listed above and remove the infinite loop at the end of main(), your code compiles and runs successfully for me. That suggests that either one of the listed points is the problem, or the problem is in code that you didn't post.

Accessing the 'strdup' of a static array from a different file

I use the get_sessionid() function below from a thread function and then try to free that pointer.
static char sessionid[SESSIONID_LEN] = { '\0' };
static void generate_sessionid() {
char set[] = "0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int len;
memset(sessionid, 0, sizeof(char) * SESSIONID_LEN);
for (len = 0; len < SESSIONID_LEN; len++) {
size_t index = (double) rand()/RAND_MAX*(sizeof(set) - 1);
sessionid[len] = set[index];
}
}
char *get_sessionid() {
if (strlen(sessionid) == 0) generate_sessionid();
return strdup(sessionid);
}
When I debug into the thread function from which I call the above get_sessionid, I noticed that the session id returned is not NULL, but the program crashes with SIGABRT immediately when I try to free that pointer. I don't double free the pointer either which can raise an abort signal. I am not sure if thread safety is an issue here.
Also the thread function is defined in a different file.
Edit:
I made the change as was suggested:
static char sessionid[SESSIONID_LEN+1] = { '\0' };
I still get SIGABRT after this edit.
Another thing to mention: I don't get this signal on other machines that I have but only on 1 particular machine that runs Debian Squeeze (Linux kernel: 2.6.32-5-amd64)
Edit 2:
From a different thread function, a segmentation fault is thrown when trying to access the pointer returned by get_sessionid(): SIGSEGV. This error is thrown on all the machines (unlike the previous error) and is reproducible.
And when I debug and try to print the value of the returned pointer in the calling thread function, I get:
<Address 0xfffffffffc005080 out of bounds>
You should define sessionid as
static char sessionid[SESSIONID_LEN+1] = { '\0' };
Then after
for (len = 0; len < SESSIONID_LEN; len++) {
sessionid still a valid C string (a sequence of characters and a '\0'), which is required by strdup().

Resources