I know this is a very old thread and not many of you are still around. But let me try my luck once more.
I can confirm that my APE server sometimes crashes a few hours after being restarted.
Oct 13 01:21:03 server56405 kernel: [8981559.624862] traps: aped_2[19153] general protection ip:418dce sp:7ffeff989060 error:0 in aped_2[400000+2a000]
I had recompiled the code a few years ago (to increase memory) so I guess I have got the last corrections.
The error is 0, pointing to a division by 0. Which I find a bit strange here. I don't see any division in the code below.
The ip given above leads to ape_disconnect() function from servers.c.
And more precisely to the line:
if (co->fd == sub->client->fd) {...
I suspect the error does not come from this if statement, but rather the inside of the if.
It could be the call to http_headers_free()
Or most likely the line: deluser(sub->user, g_ape);
I don't expect a full resolution of the case and will not recompile a modified version of the code. But here are a few questions I have. If you have any clue for any of them, let me know!
1) From the general protection error line, is there any way to be more precise as to where the general protection exactly kicks in? Can we know if it is on the if statement or below? Could it be in an inner function?
2) My best guess is that the problem is related to deleting users or sub-users. And it looks to me that users that were connected before the program was restarted find a way to interact with the new instance and make it crash (like a non-existent user asks to logout and boom!).
Do you have any clue how this can be possible?
If I knew that, I could maybe modify my client so that it does not send a request that makes a new instance crash.
Some of the C code below.
Many thanks!
static void ape_disconnect(ape_socket *co, acetables *g_ape){
subuser *sub = (subuser *)(co->attach);
if (sub != NULL) {
if (sub->wait_for_free == 1) {
free(sub);
co->attach = NULL;
return;
}
// THIS IS WHERE THE GENERAL PROTECTION KICKS IN.
// THIS IS WHERE THE GENERAL PROTECTION KICKS IN.
// THIS IS WHERE THE GENERAL PROTECTION KICKS IN.
// THIS IS WHERE THE GENERAL PROTECTION KICKS IN.
// THIS IS WHERE THE GENERAL PROTECTION KICKS IN. ------------>>>
if (co->fd == sub->client->fd) { <<<<<<<<<<-------------------------------------------------------------------------
sub->headers.sent = 0;
sub->state = ADIED;
http_headers_free(sub->headers.content);
sub->headers.content = NULL;
if (sub->user != NULL) {
if (sub->user->istmp) {
deluser(sub->user, g_ape);
co->attach = NULL;
}
}
}
}
}
void http_headers_free(http_headers_response *headers){
struct _http_headers_fields *fields;
if (headers == NULL) {return;}
fields = headers->fields;
while(fields != NULL) {
struct _http_headers_fields *tmpfields = fields->next;
free(fields->value.val);
free(fields);
fields = tmpfields;
}
free(headers);
}
void deluser(USERS *user, acetables *g_ape){
if (user == NULL) {
return;
}
left_all(user, g_ape);
FIRE_EVENT_NULL(deluser, user, user->istmp, g_ape);
/* kill all users connections */
clear_subusers(user, g_ape);
hashtbl_erase(g_ape->hSessid, user->sessid);
g_ape->nConnected--;
if (user->prev == NULL) {
g_ape->uHead = user->next;
} else {
user->prev->next = user->next;
}
if (user->next != NULL) {
user->next->prev = user->prev;
}
clear_sessions(user);
clear_properties(&user->properties);
destroy_pipe(user->pipe, g_ape);
/* TODO Add Event */
free(user);
}
void left_all(USERS *user, acetables *g_ape){
CHANLIST *list, *tList;
if (user == NULL) {
return;
}
list = user->chan_foot;
while (list != NULL) {
tList = list->next;
left(user, list->chaninfo, g_ape);
list = tList;
}
}
void clear_subusers(USERS *user, acetables *g_ape){
while (user->subuser != NULL) {
delsubuser(&(user->subuser), g_ape);
}
}