'pthread_create argument changes
I'm experiencing that the argument passed to new thread are corrupted.
static int hm_create_zone_thread(zone_threads_t *zone_thread) {
int ret;
int ret_val;
pthread_attr_t attr;
ret_val = OK;
ret = pthread_attr_init(&attr);
if (ret != 0) {
debug(hm->dbg, DEBUG_ERR, "%s(): Error creating thread_attr for zone '%" PRIu64 "': %s.\n", __func__, zone_thread->id, strerror(ret));
ret_val = ERR;
goto return_point;
}
ret = pthread_attr_setstacksize(&attr, hm->stack_size);
if (ret != 0) {
debug(hm->dbg, DEBUG_ERR, "%s(): Error setting stack for zone '%" PRIu64 "': %s.\n", __func__, zone_thread->id, strerror(ret));
ret_val = ERR;
goto return_point;
}
ret = pthread_create(&zone_thread->thread, &attr, hm_start_zone, zone_thread);
if (ret == 0) {
/* Zone thread started successfully*/
usleep(1000);
} else { /**/
// TODO!!! Log error, but keep creating other threads.
debug(hm->dbg, DEBUG_ERR, "%s(): Error creating thread for zone '%" PRIu64 "': %s.\n", __func__, zone_thread->id, strerror(ret));
ret_val = ERR;
}
pthread_attr_destroy(&attr);
return_point:
return ret_val;
}
When I debug my code, I see that zone_thread points to some sensible area, and when hm_start_zone() is executed, it gets completely different pointer value. My program then gets segfault, hence the pointer points to non existing memory.
Breakpoint 1, hm_create_zone_thread (zone_thread=0x5555555cbfb0) at /home/lev/git/lbms/host/home_manager/hmd/src/hm.c:190
190 ret = pthread_create(&zone_thread->thread, &attr, hm_start_zone, zone_thread);
(gdb) n
[New Thread 0x7ffff7fcb700 (LWP 55270)]
Thread 2 "hmd" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7fcb700 (LWP 55270)]
0x000055555555e190 in hm_start_zone (arg=<error reading variable: Cannot access memory at address 0x7ffff7fab198>)
at /home/lev/git/lbms/host/home_manager/hmd/src/hm.c:215
215 static void *hm_start_zone(void *arg) {
(gdb)
It is interesting that if I replace the &attr from the pthread_create() call with NULL, everything works fine. I certainly don't want to do that.
Edit:
The code that calls hm_create_zone_thread() is as follows:
int hm_start_zones(void) {
int ret, ret_val;
static char condition[1024];
zone_t zone;
zone_threads_t *current_zone_thread;
ret_val = OK;
sprintf(condition, "stat=%d", hm_zone_enabled);
zone.data_state = db_data_init;
while (zone.data_state != db_data_last) {
ret = db_query_zone(hm, &zone, condition);
if (ret != OK) {
ret_val = ERR;
break;
}
if (zone.data_state == db_data_valid) {
/*Add a new member to the chained list*/
hm_lookup_zone(zone.id, ¤t_zone_thread);
if (current_zone_thread != NULL) { /*already created*/
/*TODO!!! What to do if the zone is there, but it is stopped, or in error state?*/
continue;
}
ret = hm_add_new_zone(zone.id);
if (ret == ERR) {
ret_val = ERR;
break; /*Give up*/
}
} else {
break; //No more zones in the database.
}
}
/*Start zones*/
for (current_zone_thread = zones_head; current_zone_thread != NULL;) {
hm_create_zone_thread(current_zone_thread);
current_zone_thread = current_zone_thread->next;
}
/*TODO!!! Check for stopped zones*/
return ret_val;
}
Solution 1:[1]
Solved by enlarging the stack size to 8MB. I originally set the stack to 2*PTHREAD_STACK_MIN. This is strange.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Lev |
