memcpy segmentation fault. Misalignment of data structure boundaries - c

I am trying to debug this error but have not been able to do it for a while now. I have tried to use memmove as an alternative but that also results in a segmentation fault.
The link to the code in this question is posted at - http://pastebin.com/hiwV5G04
Can someone please help me understand what am I doing wrong ?
//------------------------------------------------------------------------
// Somewhere in the main function, This is the piece of code I am executing
//------------------------------------------------------------------------
SslDecryptSession *ssl_session = malloc(sizeof(struct _SslDecryptSession ));
ssl_session->client_random.data = NULL; //Make the stuff point somewhere. Else can use malloc also here. Not sure if this is a problem
ssl_session->server_random.data= NULL;
const u_char *payload; /* Packet payload */
//Case for client random
printf("Client Random ");
for (cs_id = 11; cs_id < 43; cs_id++){
printf("%hhX", payload[cs_id] );
}
printf("\n");
cs_id=11;
ssl_session->client_random.data_len=32;
// Segmentation fault here
memcpy(ssl_session->client_random.data, payload[cs_id], 32);
The definitions of the structures involved are -
typedef struct _SslDecryptSession {
guchar _master_secret[SSL_MASTER_SECRET_LENGTH];
guchar _session_id[256];
guchar _client_random[32];
guchar _server_random[32];
StringInfo session_id;
StringInfo session_ticket;
StringInfo server_random;
StringInfo client_random;
StringInfo master_secret;
StringInfo handshake_data;
StringInfo pre_master_secret;
guchar _server_data_for_iv[24];
StringInfo server_data_for_iv;
guchar _client_data_for_iv[24];
StringInfo client_data_for_iv;
gint state;
SslCipherSuite cipher_suite;
SslDecoder *server;
SslDecoder *client;
SslDecoder *server_new;
SslDecoder *client_new;
gcry_sexp_t private_key;
StringInfo psk;
guint16 version_netorder;
StringInfo app_data_segment;
SslSession session;
} SslDecryptSession;
typedef struct _StringInfo {
guchar *data;
guint data_len;
} StringInfo
The output from gdb is this
b 1985 // Putting a break point at line 1985 in my source code.
//Here this is eqvialent to line 83, that is "ssl_session->client_random.data_len=32;"
Breakpoint 1 at 0x403878: file Newversion.c, line 1985.
run //run the code in gdb
At breakpoint 1 the following info is in the variables
p ssl_session
$1 = (SslDecryptSession *) 0x60fc50 // I put some data in ssl_session->version_netorder earlier. So it is not null here. Everything works fine here
p ssl_session->client_random.data
$2 = (guchar *) 0x0
p ssl_session->client_random.data_len
$3 = 32
step // Execute 1 more line in the code
// I reach at the memcpy line and I get this error then
Breakpoint 1, got_packet (args=0x0, header=0x7fffffffe2c0, packet=0x7ffff6939086 "P=\345\203\376\177") at Newversion.c:1995
1995 memcpy(ssl_session->client_random.data, payload[cs_id], 32);
(gdb)
(gdb) s
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:27
27 ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.
(gdb)
28 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
29 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
30 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
31 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
32 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
33 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
34 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
35 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb)
Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35
35 in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S

There's many things that doesn't seems right with the code. The problematic line is :
memcpy(ssl_session->client_random.data, payload[cs_id], 32);
This line will copy what is pointed by payload[cs_id] at the adress pointed by ssl_session->client_random.data. Will do this for 32 bytes.
You provided the content of payload to memcpy instead of it's address, therefore the warning you get at compilation.
You probably meant something like
memcpy(ssl_session->client_random.data, &payload[cs_id], 32); // Note the & symbol
Also, there is a comment in your code stating that you are unsure whether you should use malloc or not. You do.
In the snippet of code you provided, payload is not initilized (therefore, unpredictable value) and ssl_session->client_random.data is initilized with NULL. This means you try to write at address 0, which will raise a segfault for sure. Moreover, before writing at address 0, you read a random address in the memory, which will most likely raise an exception as well.
To solve the issue, make sure your OS has given you a memory space to use before reading/writing in it.
const u_char payload[43]; // 43 is based on the example you provided
...
ssl_session->client_random.data = malloc(sizeof(u_char)*32); // Also based on your example
...
memcpy(ssl_session->client_random.data, &payload[cs_id], 32);
Hope this helps.

1-you forget to allocate the memory.
2- memcpy(ssl_session->client_random.data, &payload[cs_id], 32*sizeof(u_char)
SslDecryptSession *ssl_session = malloc(sizeof(struct _SslDecryptSession ));
ssl_session->client_random.data = NULL; //Make the stuff point somewhere. Else can use malloc also here. Not sure if this is a problem
ssl_session->server_random.data= NULL;
const u_char *payload; /* Packet payload */
//Case for client random
printf("Client Random ");
for (cs_id = 11; cs_id < 43; cs_id++){
printf("%hhX", payload[cs_id] );
}
printf("\n");
cs_id=11;
ssl_session->client_random.data_len=32;
guchar *pData = malloc(32*sizeof(guchar));
ssl_session->client_random.data = pData;
memcpy(ssl_session->client_random.data, &payload[cs_id], 32*sizeof(u_char);

The offending code is:
memcpy(ssl_session->client_random.data, payload[cs_id], 32);
With payload defined as:
const u_char *payload;
You seem to have a type mismatch for operand 2 of memcpy, you do not pass a pointer but an integer. The compiler should complain with a warning, and such warnings should not be ignored.
Did you mean to use memset() to initialize the data instead of memcpy()?

Related

What does it mean if a struct pointer has a value of 0xfbad2488

I'm writing a program that uses the following structures to store information:
/* Structure used to hold a graph vertex information. */
typedef struct graph_vertex
{
int identifier;
struct graph_vertex *next_vertex_p;
struct graph_edge *edge_list_p;
boolean_t visited;
} graph_vertex_t;
/* Structure used to hold a graph edge information. */
typedef struct graph_edge
{
struct graph_vertex *adjac_vertex_p;
struct graph_edge *next_edge_p;
} graph_edge_t;
Basically, the first structure is used to store a list of vertices while the second is used by the first to store the connections(edges). Now I'm trying to look through the list of edges for a certain vertex I found and do an operation. I use the following code for this:
/* Find the right vertex to explore*/
for (curr_graph = start;
curr_graph != NULL && curr_graph->identifier != list[0];
curr_graph = curr_graph->next_vertex_p);
/* Explore all it's edges for new vertices. */
for (curr_edge_list = curr_graph->edge_list_p;
curr_edge_list != NULL;
curr_edge_list = curr_edge_list->next_edge_p)
{
printf("ID: %d ,", curr_edge_list->adjac_vertex_p->identifier);
/*do more stuff...*/
Currently I'm getting a segmentation fault on the line with the printf which I checked using gdb. I also checked the values of curr_edge_list , curr_edge_list->adjac_vertex_p and curr_edge_list->adjac_vertex_p->identifier :
Program received signal SIGSEGV, Segmentation fault.
0x0000555555554c9f in start_visit_graph_bf (start=0x7fffffffdee0,
starting_identifier=1) at explore_graph.c:170
170 printf("ID: %d ,", curr_edge_list->adjac_vertex_p->identifier);
(gdb) print curr_edge_list
$1 = (graph_edge_t *) 0x5555557574a0
(gdb) print curr_edge_list->adjac_vertex_p
$2 = (struct graph_vertex *) 0xfbad2488
(gdb) print curr_edge_list->adjac_vertex_p->identifier
Cannot access memory at address 0xfbad2488
(gdb)
My first instinct was that the value 0xfbad2488 was a code used to describe NULL, so I checked that curr_edge_list->adjac_vertex_p wasn't equal to NULL before the printf statement. This was not the case. Therefor my question is: What is the value 0xfbad2488 and what does it mean if a variable has that value? Also which operations cause this kind of behavior?
My first instinct was that the value 0xfbad2488 was a code used to describe NULL
No, NULL will look like this in GDB:
(gdb) print curr_edge_list->adjac_vertex_p
$2 = (struct graph_vertex *) 0x0
What you want to do is figure out which location is being overwritten (print &curr_edge_list->adjac_vertex_p), and set a watchpoint on it:
(gdb) watch -l curr_edge_list->adjac_vertex_p
Then run your program again. If your program is deterministic (doesn't use threads), you should see the location acquire initial value (should look similar to your other pointers, e.g. 0x55555575..., and then you should see it being overwritten with 0xfbad2488. That is exactly the point where the bug is (where your data is getting corrupted).

segmentation fault invalid memory 0x0

I have an issue with my pointer to a structure variable. I just started using GDB to debug the issue. The application stops when it hits on the line of code below due to segmentation fault. ptr_var is a pointer to a structure
ptr_var->page = 0;
I discovered that ptr_var is set to an invalid memory 0x0 after a series of function calls which caused the segmentation fault when assigning the value "0" to struct member "page". The series of function calls does not have a reference to ptr_var. The old address that used to be assigned to ptr_var is still in memory. I can still still print the values of members from the struct ptr_var using the old address. GDB session below shows that I am printing a string member of the struct ptr_var using its address
(gdb) x /s *0x7e11c0
0x7e0810: "Sample String"
I couldn't tell when the variable ptr_var gets assigned an invalid address 0x0. I'm a newbie to GDB and an average C programmer. Your assistance in this matter is greatly appreciated. Thank you.
What you want to do is set a watchpoint, GDB will then stop execution every time a member of a struct is modified.
With the following example code
typedef struct {
int val;
} Foo;
int main(void) {
Foo foo;
foo.val = 5;
foo.val = 10;
}
Drop a breakpoint at the creation of the struct and execute watch -l foo.val Then every time that member is changed you will get a break. The following is my GDB session, with my input
(gdb) break test.c:8
Breakpoint 3 at 0x4006f9: file test.c, line 8.
(gdb) run
Starting program: /usr/home/sean/a.out
Breakpoint 3, main () at test.c:9
9 foo.val = 5;
(gdb) watch -l foo.val
Hardware watchpoint 4: -location foo.val
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 0
New value = 5
main () at test.c:10
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 5
New value = 10
main () at test.c:11
(gdb) cont
If you can rerun, then break at a point where ptr_var is correct you can set a watch point on ptr_var like this: (gdb) watch ptr_var. Now when you continue every time ptr_var is modified gdb should stop.
Here's an example. This does contain undefined behaviour, as I'm trying to reproduce a bug, but hopefully it should be good enough to show you what I'm suggesting:
#include <stdio.h>
#include <stdint.h>
int target1;
int target2;
void
bad_func (int **bar)
{
/* Set contents of bar. */
uintptr_t ptr = (uintptr_t) bar;
printf ("Should clear %p\n", (void *) ptr);
ptr += sizeof (int *);
printf ("Will clear %p\n", (void *) ptr);
/* Bad! We just corrupted foo (maybe). */
*((int **) ptr) = NULL;
}
int
main ()
{
int *foo = &target1;
int *bar = &target2;
printf ("&foo = %p\n", (void *) &foo);
printf ("&boo = %p\n", (void *) &bar);
bad_func (&bar);
return *foo;
}
And here's a gdb session:
(gdb) break bad_func
Breakpoint 1 at 0x400542: file watch.c, line 11.
(gdb) r
&foo = 0x7fffffffdb88
&boo = 0x7fffffffdb80
Breakpoint 1, bad_func (bar=0x7fffffffdb80) at watch.c:11
11 uintptr_t ptr = (uintptr_t) bar;
(gdb) up
#1 0x00000000004005d9 in main () at watch.c:27
27 bad_func (&bar);
(gdb) watch foo
Hardware watchpoint 2: foo
(gdb) c
Continuing.
Should clear 0x7fffffffdb80
Will clear 0x7fffffffdb88
Hardware watchpoint 2: foo
Old value = (int *) 0x60103c <target1>
New value = (int *) 0x0
bad_func (bar=0x7fffffffdb80) at watch.c:18
18 }
(gdb)
For some reason the watchpoint appears to trigger on the line after the change was made, even though I compiled this with -O0, which is a bit of a shame. Still, it's usually close enough to help identify the problem.
For such kind of problems I often use the old electric fence library, it can be used to find bug in "software that overruns the boundaries of a malloc() memory allocation". You will find all the instructions and basic usage at this page:
http://elinux.org/Electric_Fence
(At the very end of the page linked above you will find the download link)

C - Freeing pointers inside an array

I've been trying to have all my pointers that I use malloc to initialize to be inside an array of pointers (or a pointer of pointers, perhaps), so that I can then just go through that array and free each pointer with something like free(ptr_array[i]); and not have to free each one individually.
I believe that this is possible, but I am having some trouble with my code, as the function that is supposed to free everything (and I would rather keep it all in a separate function, if possible) is apparently unable to properly edit the "sub-pointers", and seemingly they're being copied unlike the "main pointer".
Here's the code, which has me stumped:
#include <stdlib.h>
#include <stdio.h>
void free_test(int** arg){
printf("\tReceived arg addr: %p\n",arg);
printf("\tFreeing arg[0] = %p\n",arg[0]);
//And, just to MAKE SURE that arg[0] is ver, we do this:
printf("\tIn-function ver[0] = %d\n",arg[0][0]);
arg[0][0] = 2;
printf("\tIn-function ver[0] = %d\n",arg[0][0]);
free(arg[0]); //This one doesn't work...
free(arg); //This one works though.
}
int main(){
int** var;
int* ver;
int i;
printf("ver addr 1: %p\n", ver);
ver = malloc( sizeof(int) * 3 );
printf("ver addr 2: %p\n", ver);
for(i=0;i<3;i++){
ver[i] = 5*i;
}
for(i=0;i<3;i++){
printf("ver[%d]: %d\t(# %p)\n",i,ver[i],&(ver[i]));
}
printf("var addr 1: %p\n", var);
var = malloc( sizeof(int *) );
printf("var addr 2: %p\n", var);
var[0] = ver;
printf("var[0] addr = %p\n", var[0]);
free_test(var);
printf("ver[0] new value: %d\n", ver[0]);
//free(var); (free(arg) works in the function, so this one throws an error.)
printf("So far so good, now break.\n");
free(ver);
printf("Didn't break. :(\n");
return 0;
}
And this is the output it currently gives me:
ver addr 1: 0x8048679
ver addr 2: 0x8b0f008
ver[0]: 0 (# 0x8b0f008)
ver[1]: 5 (# 0x8b0f00c)
ver[2]: 10 (# 0x8b0f010)
var addr 1: 0xad7ff4
var addr 2: 0x8b0f018
var[0] addr = 0x8b0f008
Received arg addr: 0x8b0f018
Freeing arg[0] = 0x8b0f008
In-function ver[0] = 0
In-function ver[0] = 2
ver[0] new value: 0
So far so good, now break.
Didn't break. :(
I'm not too great with C, and thus any help would be appreciated. Specially since the value of ver[0] is altered inside the function, but not outside, and I'm guessing that will have to do with why free(...) doesn't work too.
Thanks in advance.
Well my knowledge of C is fading, but IIRC subsequent memory freeing causes undefined behaviour. Thus you are not guaranteed to recive any errors. If I understand it right the behaviour will be varying heavily depending on a particular OS, compiler and stdlib implementation (and even a particular program run).
P.S. My VS2012 VC++ compiler definetly breaks on free(ver);. The output is:
ver addr 1: CCCCCCCC
ver addr 2: 00B8AFF0
ver[0]: 0 (# 00B8AFF0)
ver[1]: 5 (# 00B8AFF4)
ver[2]: 10 (# 00B8AFF8)
var addr 1: CCCCCCCC
var addr 2: 00B85BF0
var[0] addr = 00B8AFF0
Received arg addr: 00B85BF0
Freeing arg[0] = 00B8AFF0
In-function ver[0] = 0
In-function ver[0] = 2
ver[0] new value: -17891602
So far so good, now break.
I have tested your code on gcc 4.6.3 and find that this program does not have any memory leaks using valgrind. And when I delete the line "free(ver)" in main, the program runs perfectly and does not have any memory leak either. I think free_test routine has successfully freed those two malloc you have in main. As for why there is not any coredump pops out when freeing the var again in the program, it depends on different OS implementation.
Test it with valgrind and you will find it useful if you want to check memory leaks involving malloc and free.
Use
"* (*(arg+0)+0)"
instead of [][].
Syntax like [][]...[] only dereference pointer once. Each [] only change the semantic of pointer (how many location it jumps when +1), have nothing to do with dereference times.
void free_test(int** arg){
printf("\tReceived arg addr: %p\n",arg);
printf("\tFreeing arg[0] = %p\n",arg[0]);
//And, just to MAKE SURE that arg[0] is ver, we do this:
printf("\tIn-function ver[0] = %d\n",arg[0][0]);
arg[0][0] = 2;
// ^^^^^^^^^^^^^^ here, arg[0][0] is the same as arg[0], so arg[0] is changed, not the location arg[0] points to.
printf("\tIn-function ver[0] = %d\n",arg[0][0]);
free(arg[0]); //This one doesn't work...
free(arg); //This one works though.
}
Why this comment in your code?
free(arg[0]); //This one doesn't work...
I think it did work, and it freed the data var points to, and then you freed it again.
Your debug data shows
ver addr 2: 00B8AFF0
Freeing arg[0] = 00B8AFF0
If you comment out the first time you freed it, it still fails?
and you used it after freeing it the first time:
printf("ver[0] new value: %d\n", ver[0]); /// but you already freed that
Try using
void *xmalloc(int s) {
char *ret = malloc(s);
printf("malloc(%d)==%p\n", s, ret);
return ret;
}
void xfree(void *b) {
printf("free(%p)\n", b);
free(b)
return;
}
#define malloc xmalloc
#define free xfree
It's been a long time since I worked in C.
Initialize your variables.
int** var = NULL;
int* ver = NULL;
Before you free a block of data, set it to all zeros (or some other value).
memset(void_ptr, 0, sizeof_your_data);
It's a LOT easier to read your code if you delete all those print statements... though I know they are useful for debugging... try it (make a backup first).

Segmentation fault from a function that is not called at all

Ok, this is really freaking me out. I have a following function that just reads input and returns a string
unsigned char* readFromIn() {
unsigned char* text = malloc(1024);
if (fgets(text, 1024, stdin) != NULL) { <--This is what's causing segmentation fault
int textLen = strlen(text);
if (textLen > 0 && text[textLen - 1] == '\n')
text[textLen - 1] = '\0'; // getting rid of newline character
return text;
}
else {
free(text);
return NULL;
}
}
The thing is, this function isn't called anywhere and just to confirm, I changed the name of the function to something crazy like 9rawiohawr90awrhiokawrioawr and put printf statement on the top of the function.
I'm genuinely not sure why an uncalled function might cause a segmentation fault error.
I'm using gcc 4.6.3 on ubuntu.
Edit: I know that the line
if (fgets(text, 1024, stdin) != NULL) {
is the offending code because as soon as i comment out that conditional, no segmentation error occurs.
I know that the function is NOT being called because i'm seeing no output of the printf debug statement I put.
Edit2: I've tried changing the type from unsigned char to char. Still segmentation error. I will try to get gdb output.
Edit3: gdb backtrace produced the following
#0 0xb7fa5ac2 in _IO_2_1_stdin_ () from /lib/i386-linux-gnu/libc.so.6
#1 0xb7faf2fb in libwebsocket_create_context (info=0xbffff280) at libwebsockets.c:2125
#2 0x0804a5bb in main()
doing frame 0,1,2 doesn't output anything interesting in particular.
Edit4: I've tried all of the suggestions in the comment, but to no avail, I still get the same segmentation fault.
So I installed a fresh copy of Ubuntu on a virtual OS and recompiled my code. Still the same issue occurs.
It seems to me the problem is in either some obscurity going on in my code or the library itself. I've created a minimal example demonstrating the problem:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libwebsockets.h>
unsigned char* readFromIn() {
unsigned char* text = malloc(1024);
if (fgets(text, 1024, stdin) != NULL) { <--SEGMENTATION FAULT HERE
int textLen = strlen(text);
if (textLen > 0 && text[textLen - 1] == '\n')
text[textLen - 1] = '\0';
return text;
}
else {
free(text);
return NULL;
}
}
int callback_http(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len)
{
return 0;
}
static struct libwebsocket_protocols protocols[] = {
/* first protocol must always be HTTP handler */
{
"http-only", // name
callback_http, // callback
0 // per_session_data_size
}
};
int main(void) {
printf("Initializing Web Server\n");
// server url will be http://localhost:8081
int port = 8081;
const char *interface = NULL;
struct libwebsocket_context *context;
// we're not using ssl
const char *cert_path = NULL;
const char *key_path = NULL;
// no special options
int opts = 0;
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
info.port = port;
info.iface = interface;
info.protocols = protocols;
info.extensions = libwebsocket_get_internal_extensions();
info.ssl_cert_filepath = NULL;
info.ssl_private_key_filepath = NULL;
info.gid = -1;
info.uid = -1;
info.options = opts;
context = libwebsocket_create_context(&info);
if (context == NULL) {
fprintf(stderr, "libwebsocket init failed\n");
return 0;
}
printf("starting server...\n");
while (1) {
libwebsocket_service(context, 50);
}
printf("Shutting server down...\n");
libwebsocket_context_destroy(context);
return 0;
}
And here's how I compiled my code
gcc -g testbug.c -o test -lwebsockets
Here's the library I'm using
http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/tag/?id=v1.23-chrome32-firefox24
You will see that I'm not calling the function readFromIn() yet, segmentation fault occurs as soon as you try to run the executable.
I've re-ran gdb and this time, backtrace and the frames tell me a little bit more info.
(gdb) run
Starting program: /home/l46kok/Desktop/websocketserver/test
Initializing Web Server
[1384002761:2270] NOTICE: Initial logging level 7
[1384002761:2270] NOTICE: Library version: 1.3 unknown-build-hash
[1384002761:2271] NOTICE: Started with daemon pid 0
[1384002761:2271] NOTICE: static allocation: 4448 + (12 x 1024 fds) = 16736 bytes
[1384002761:2271] NOTICE: canonical_hostname = ubuntu
[1384002761:2271] NOTICE: Compiled with OpenSSL support
[1384002761:2271] NOTICE: Using non-SSL mode
[1384002761:2271] NOTICE: per-conn mem: 124 + 1360 headers + protocol rx buf
[1384002761:2294] NOTICE: Listening on port 8081
Program received signal SIGSEGV, Segmentation fault.
0xb7fb1ac0 in _IO_2_1_stdin_ () from /lib/i386-linux-gnu/libc.so.6
(gdb) backtrace
#0 0xb7fb1ac0 in _IO_2_1_stdin_ () from /lib/i386-linux-gnu/libc.so.6
#1 0xb7fcc2c6 in libwebsocket_create_context () from /usr/local/lib/libwebsockets.so.4.0.0
#2 0x080488c4 in main () at testbug.c:483
(gdb) frame 1
#1 0xb7fcc2c6 in libwebsocket_create_context () from /usr/local/lib/libwebsockets.so.4.0.0
(gdb) frame 2
#2 0x080488c4 in main () at testbug.c:483
483 context = libwebsocket_create_context(&info);
So yeah.. I think I gave all the information at hand.. but I'm genuinely not sure what the issue is. The program causes segmentation fault at line 483 but the issue is gone when I comment out the offending function that's not being called.
Probably you're missing something when initializing libwebsockets.
Indeed, recompiling libwebsockets with debug reveals that:
GNU gdb (GDB) 7.6.1 (Debian 7.6.1-1)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/vili/x...done.
(gdb) r
Starting program: /home/vili/./x
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Initializing Web Server
[1384020141:5692] NOTICE: Initial logging level 7
[1384020141:5692] NOTICE: Library version: 1.2
[1384020141:5693] NOTICE: Started with daemon pid 0
[1384020141:5693] NOTICE: static allocation: 5512 + (16 x 1024 fds) = 21896 bytes
[1384020141:5693] NOTICE: canonical_hostname = x220
[1384020141:5693] NOTICE: Compiled with OpenSSL support
[1384020141:5693] NOTICE: Using non-SSL mode
[1384020141:5693] NOTICE: per-conn mem: 248 + 1328 headers + protocol rx buf
[1384020141:5713] NOTICE: Listening on port 8081
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bc2080 in _IO_2_1_stderr_ () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff7bc2080 in _IO_2_1_stderr_ () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7bcd83c in libwebsocket_create_context (info=0x7fffffffe580)
at libwebsockets.c:2093
#2 0x0000000000400918 in main () at x.c:66
(gdb) up
#1 0x00007ffff7bcd83c in libwebsocket_create_context (info=0x7fffffffe580)
at libwebsockets.c:2093
2093 info->protocols[context->count_protocols].callback(context,
(gdb) p context->count_protocols
$1 = 1
(gdb) p info->protocols[1]
$2 = {
name = 0x7ffff7bc2240 <_IO_2_1_stdin_> "\210 \255", <incomplete sequence \373>, callback = 0x7ffff7bc2080 <_IO_2_1_stderr_>,
per_session_data_size = 140737349689696, rx_buffer_size = 0,
owning_server = 0x602010, protocol_index = 1}
(gdb)
Quite likely you need to close the array of libwebsocket_protocols with a special entry (NULL) so that the lib will know how many entries it got via info->protocols.
Edit: yep, check the docs: http://jsk.pp.ua/knowledge/libwebsocket.html
Array of structures listing supported protocols and a protocol- specific callback for each one. The list is ended with an entry that
has a NULL callback pointer.

Malloc of 2 bytes gives issues

I am trying to use a malloc of short, something like
typedef union _SOME_STRUCT_ {
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
} x;
USHORT word;
} SOME_STRUCT, *PSOME_STRUCT;
PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));
if (p) {
p->x.u = 0;
}
free (p); // **** RANDOMLY CRASHING HERE ****
I am debugging for a couple of days and clueless,
Note(edited): Linux, and gcc Version 3.4.6 20060404
ISSUE FOUND USING VALGRIND
But then, I would like to document it here so that my fellow developers might be aware of such a situation ...
I had actually defined the structure as
typedef union _SOME_STRUCT_ {
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
} x;
USHORT word;
} ALBUM, *PALBUM;
and some-where else in the code I had also defined
#define ALBUM "album"
And so, sizeof (ALBUM) was referring to the #define value rather than the typedef and hence the issue.
The thing that amazes me is,
Is this allowed in C?
Try to pass your program through valgrind , an open source program and totaly free, maybe it could help you to see where is the issue. Don't forget to compile with debug symbols: gcc -g [etc] .
Hope this help..
This version of the code works for me.
#include <stdio.h>
#define USHORT unsigned short
typedef union _SOME_STRUCT_ {
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
} x;
USHORT word;
} SOME_STRUCT, *PSOME_STRUCT;
int
main(int c, char *argv[])
{
PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));
if (p) {
p->x.u = 0;
}
free (p); // **** Properly exiting after this ****
}
This is GDB debug from a Cygwin on Windows XP.
(gdb) p/x sizeof(PSOME_STRUCT)
$1 = 0x4
(gdb) p/x sizeof(p)
$2 = 0x4
(gdb) p/x sizeof(*p)
$3 = 0x2
(gdb) n
23 if (p) {
(gdb) p/x *p
$4 = {x = {u = 0xc, v = 0x4, w = 0x3}, word = 0x534c}
Ignore the values in $4, data is uninitialized.
Program exited normally.
Do you have something else in the code besides these lines?
Edit: and, free(0); is a valid operation.
Might be an alignment issue. Does it still crash if you do something like this:
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
USHORT :4;
} x;
The problem is not with the code but something that is happening before or in another thread.
I would reduce sections of the program until it stops crashing and then add it back in step by step until you figure out what section is causing this. Depending on the OS/Platform you could also try some memory checking tools, valgrind/_crtdebug etc..
If this issue is happening where you could debug it you could start your debug session with a call to memcheck.
A cause for a crash for memory is most often heap or freeing the same pointer twice.
If you're doing stuff in between the malloc and free, you could be overrunning a different array by accident and corrupting your own stack
(if 'p' doesn't happen to be in a register, and you overrun a statically-allocated array and hit the place on the stack where 'p' is stored, you will then later attempt to free random crap, hence the segfault)
You're unconditionally calling free() without checking if the malloc succeeded, so if the malloc failed and p is a NULL pointer, then you're calling free(NULL).
Move the free inside the if (p) block.
This might not be the cause of the crashes, and shouldn't be if not memory-constrained, but is a bug nonetheless.
Added later: doh, free(NULL) is explicitly allowed, per http://www.opengroup.org/onlinepubs/009695399/functions/free.html -- sorry.
What if you put free(p) in your if? Maybe (unlikely) malloc is failing...

Resources