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

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().

Related

Segmentation fault in c (C90), Whats the problem?

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.

C KERN_INVALID_ADDRESS in regnexec()

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.

C memory management in server application

I am student and I am writing HTTP proxy application in C. I have trouble with memory management. In all my previous applications I simply wrote a wrapper around malloc which aborted when malloc failed.
void *xmalloc(size_t size)
{
void *ptr;
assert(size);
ptr = malloc(size);
if (!ptr)
abort();
return ptr;
}
This I now find insufficient as I just want to refuse client and continue serving other clients when memory allocation fails due to temporary shortage of memory. If I don't want to clutter my code with checks after each malloc call (I have quite lot of them per function in parsing code), what are other options to handle memory management and which one is the best for my purposes and how what is a common way for server applications to handle memory management and shortage of memory?
Consider this function from my current code which parses one line from header portion of HTTP message (xstrndup calls xmalloc):
int http_header_parse(http_hdr_table *t, const char *s)
{
const char *p;
const char *b;
char *tmp_name;
char *tmp_value;
int ret = -1;
assert(t);
assert(s);
p = b = s;
/* field name */
for (; ; p++) {
if (*p == ':') {
if (p-b <= 0) goto out;
tmp_name = xstrndup(b, p-b);
b = ++p;
break;
}
if (is_ctl_char(*p) || is_sep_char(*p)) goto out;
}
while (*p == ' ' || *p == '\t') {
p++; b++;
}
/* field value */
for (; ; p++) {
if (is_crlf(p)) {
if (p-b <= 0) goto err_value;
tmp_value = xstrndup(b, p-b);
p += 2;
break;
}
if (!*p) goto err_value;
}
http_hdr_table_set(t, tmp_name, tmp_value);
ret = 0;
xfree(tmp_value);
err_value:
xfree(tmp_name);
out:
return ret;
}
I would like to keep things simple and handle memory allocation errors at one place and to not clutter code with malloc error handling code. What should I do? Thank you.
P.S: I am writing the application to run on POSIX/Unix-like systems. Also feel free to criticize my current coding style and practices.
If you want to use a relatively low level language like C, then you shouldn't be too worried about adding something like if(tmp_value == NULL) goto out; in 2 places.
If you can't stand the idea of 2 trivial lines of extra code, then maybe try a language that supports exceptions properly (e.g. C++) and add throw/try/catch instead. Note: I really don't like C++, but using C++ would have to make more sense than implementing your own "exception like" features and an entire layer of automated resource de-allocation in C.
Modern languages give you garbage collection and exceptions. C doesn't, so you have to work hard. There's no magical solution here.
Some tips:
Create a session structure, and keep all your allocated memory pointed from it. When the session is aborted, always call a cleanup function. This way, even if you have to check for failures in many places, at least all failures are handled the same way.
You can even create a session_allocate() function, which allocates memory and keeps it on a linked list pointed from the session structure. Everything you allocate using this function would be freed when the session is destroy.
Try to concentrate all allocations in the beginning of the session. After you've allocated all you need, the rest of your code won't need to worry about failures.
If you're on a system that supports fork(), which linux does, you can run each client connection in it's own process. When a client connection is first established, you fork your main process into a child process to handle the rest of the request. Then you can abort() like you always have and only the specific client connection is affected. This is a classic unix server model.
If you don't want to or can't use fork(), you need to abort the request by throwing an exception. In C, that would be done by using setjump() when the connection is first established and then calling longjump() when out of memory is detected. This will reset execution and the stack back to where setjump() was called.
The problem is, this will leak all the resources allocated up to that point (for example, other memory allocations that had succeeded up to the point of getting out of memory). So additionally, your memory allocator will have to track all the memory allocations for each request. When longjump() is called, the setjump() return location will then have to free all the memory that was associated with the aborted request.
This is what apache does using pools. Apache uses pools to track resource allocations so it can auto free them in the case of an abort or because the code just didn't free it: http://www.apachetutor.org/dev/pools.
You should also consider the pool model and not just simply wrap malloc() so one client can't use up all the memory in the system.
Another possibility would be to use Boehm's GC by using its GC_malloc instead of malloc (you won't need to call free or GC_free); its
GC_oom_fn function pointer (called internally from GC_malloc when no memory is available any more) can be set to your particular out of memory handler (which would deny the incoming HTTP request, perhaps with a longjmp)
The major advantage of using Boehm GC is that you don't care any more about free-ing your dynamically allocated data (provided it was allocated using GC_malloc or friends, e.g. GC_malloc_atomic for data without any pointers inside).
Notice that memory management is not a modular property. The liveness of some given data is a whole program property, see garbage collection wikipage, and RAII programming idiom.
You could of course use alloca, but that has issues that mean it must be used with care. Alternatively, you can write your code so that you minimise and localise the use of malloc. For example your function above could be rewritten to localise the allocations:
static size_t field_name_length(const char *s)
{
const char *p = s;
for ( ; *p != ':'; ++p) {
if (is_ctl_char(*p) || is_sep_char(*p))
return 0;
}
return (size_t) (p - s);
}
static size_t value_length(const char *s)
{
const char *p = s;
for (; *p && !is_crlf(p); p+=2) {
/* nothing */
}
return *p ? (size_t) (p - s) : 0;
}
int http_header_parse(http_hdr_table *t, const char *s)
{
const char *v;
int ret = -1;
size_t v_len = 0;
size_t f_len = field_name_length(s);
if (f_len) {
v = s + f_len + 1;
v = s + strspn(s, " \t");
v_len = value_length(s);
}
if (v_len > 0 && f_len > 0) {
/* Allocation is localised to this block */
const char *name = xstrndup(s, f_len);
const char *value = xstrndup(v, v_len);
if (name && value) {
http_hdr_table_set(t, name, value);
ret = 0;
}
xfree(value);
xfree(name);
}
return ret;
}
Or, even better, you could modify http_hdr_table_set to accept the pointers and lengths and avoid allocation completely.

Why does segmentation fault (core dumped) error apply to my C program?

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

Running out of memory.. How?

I'm attempting to write a solver for a particular puzzle. It tries to find a solution by trying every possible move one at a time until it finds a solution. The first version tried to solve it depth-first by continually trying moves until it failed, then backtracking, but this turned out to be too slow. I have rewritten it to be breadth-first using a queue structure, but I'm having problems with memory management.
Here are the relevant parts:
int main(int argc, char *argv[])
{
...
int solved = 0;
do {
solved = solver(queue);
} while (!solved && !pblListIsEmpty(queue));
...
}
int solver(PblList *queue) {
state_t *state = (state_t *) pblListPoll(queue);
if (is_solution(state->pucks)) {
print_solution(state);
return 1;
}
state_t *state_cp;
puck new_location;
for (int p = 0; p < puck_count; p++) {
for (dir i = NORTH; i <= WEST; i++) {
if (!rules(state->pucks, p, i)) continue;
new_location = in_dir(state->pucks, p, i);
if (new_location.x != -1) {
state_cp = (state_t *) malloc(sizeof(state_t));
state_cp->move.from = state->pucks[p];
state_cp->move.direction = i;
state_cp->prev = state;
state_cp->pucks = (puck *) malloc (puck_count * sizeof(puck));
memcpy(state_cp->pucks, state->pucks, puck_count * sizeof(puck)); /*CRASH*/
state_cp->pucks[p] = new_location;
pblListPush(queue, state_cp);
}
}
}
free(state->pucks);
return 0;
}
When I run it I get the error:
ice(90175) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Bus error
The error happens around iteration 93,000.
From what I can tell, the error message is from malloc failing, and the bus error is from the memcpy after it.
I have a hard time believing that I'm running out of memory, since each game state is only ~400 bytes. Yet that does seem to be what's happening, seeing as the activity monitor reports that it is using 3.99GB before it crashes. I'm using http://www.mission-base.com/peter/source/ for the queue structure (it's a linked list).
Clearly I'm doing something dumb. Any suggestions?
Check the result of malloc. If it's NULL, you might want to print out the length of that queue.
Also, the code snippet you posted didn't include any frees...
You need to free() the memory you've allocated manually after you're done with it; dynamic memory doesn't just "free itself"

Resources