BusyBox Bug and Patch Tracking
BusyBox
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0001779 [buildroot] Architecture Specific minor always 12-15-07 15:02 09-21-08 05:42
Reporter hwstar View Status public  
Assigned To buildroot
Priority normal Resolution open  
Status assigned   Product Version
Summary 0001779: Asterisk PBX threading issues when compiled against uClibc on buildroot system (recursive lock test hangs)
Description I created a buildroot system with the development tools installed on the target.
When compiling the Asterisk PBX on the target system, the function test_for_thread_safety() which tests for recursive mutexes in main/utils.c never finishes causing asterisk.ctl to never be created. I attached a code snippet from utils.c and an strace dump in the "additional information" box below. It shows that the test thread is being created, and from within the test thread, the system never returns from the lock right after the message "Test thread body stated\n".
In the main process code, nothing happens after the the call to ast_pthread_create().

My uClibc library .config file is also attached as a file.

Are recursive mutex locks an issue in uClibc?



Additional Information Asterisk 1.4.15
uClibC 0.9.29

Code from utils.c:

AST_MUTEX_DEFINE_STATIC(test_lock);
AST_MUTEX_DEFINE_STATIC(test_lock2);
static pthread_t test_thread;
static int lock_count = 0;
static int test_errors = 0;
                                                                                
/*! \brief This is a regression test for recursive mutexes.
   test_for_thread_safety() will return 0 if recursive mutex locks are
   working properly, and non-zero if they are not working properly. */
static void *test_thread_body(void *data)
{
        printf("Test thread body started\n"); /* DEBUG */
        ast_mutex_lock(&test_lock); <<<< Never returns from this.
        lock_count += 10;
        if (lock_count != 10)
                test_errors++;
        printf("Thread body first lock\n"); /* DEBUG */
        ast_mutex_lock(&test_lock);
        lock_count += 10;
        if (lock_count != 20)
                test_errors++;
        printf("Thread body second lock\n"); /* DEBUG */
        ast_mutex_lock(&test_lock2);
        printf("Thread body first unlock\n"); /* DEBUG */
        ast_mutex_unlock(&test_lock);
        lock_count -= 10;
        if (lock_count != 10)
                test_errors++;
        printf("Thread body first unlock again!\n"); /* DEBUG */
        ast_mutex_unlock(&test_lock);
        lock_count -= 10;
        printf("Thread body second unlock again!\n"); /* DEBUG */
        ast_mutex_unlock(&test_lock2);
        if (lock_count != 0)
                test_errors++;
        printf("Test thread body done\n"); /* DEBUG */
        return NULL;
}

                                                                                
/*! \brief This is a regression test for recursive mutexes.
   test_for_thread_safety() will return 0 if recursive mutex locks are
   working properly, and non-zero if they are not working properly. */
static void *test_thread_body(void *data)
{
        printf("Test thread body started\n"); /* DEBUG */
        ast_mutex_lock(&test_lock);
        lock_count += 10;
        if (lock_count != 10)
                test_errors++;
        printf("Thread body first lock\n"); /* DEBUG */
        ast_mutex_lock(&test_lock);
        lock_count += 10;
        if (lock_count != 20)
                test_errors++;
        printf("Thread body second lock\n"); /* DEBUG */
        ast_mutex_lock(&test_lock2);
        printf("Thread body first unlock\n"); /* DEBUG */
        ast_mutex_unlock(&test_lock);
        lock_count -= 10;
        if (lock_count != 10)
                test_errors++;
        printf("Thread body first unlock again!\n"); /* DEBUG */
        ast_mutex_unlock(&test_lock);
        lock_count -= 10;
        printf("Thread body second unlock again!\n"); /* DEBUG */
        ast_mutex_unlock(&test_lock2);
        if (lock_count != 0)
                test_errors++;
        printf("Test thread body done\n"); /* DEBUG */
        return NULL;
}




# gcc -v
Using built-in specs.
Target: i586-linux-uclibc
Configured with: /home/srodgers/projects/limey-linux/limey-linux-test/buildroot/toolchain_build_i586/gcc-4.2.1/configure --prefix=/usr --build=i386-pc-linux-gnu --host=i586-linux-uclibc --target=i586-linux-uclibc --enable-languages=c --with-gxx-include-dir=/usr/include/c++ --disable-__cxa_atexit --with-gnu-ld --enable-shared --disable-nls --enable-threads --disable-multilib --with-arch=i586 --with-tune=i586
Thread model: posix
gcc version 4.2.1


strace -f asterisk yeilds:

# strace -f asterisk
execve("/usr/sbin/asterisk", ["asterisk"], [/* 22 vars */]) = 0
mmap2(NULL, 20, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f93000
stat("/etc/ld.so.cache", {st_mode=S_IFREG|0644, st_size=3664, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY) = 3
mmap2(NULL, 3664, PROT_READ, MAP_SHARED, 3, 0) = 0xb7f92000
close(3) = 0
open("/lib/libdl.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=8900, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f91000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0,\7\0\000"..., 4096) = 4096
mmap2(NULL, 12288, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f8e000
mmap2(0xb7f8e000, 4728, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xb7f8e000
mmap2(0xb7f90000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x1) = 0xb7f90000
close(3) = 0
munmap(0xb7f91000, 4096) = 0
open("/lib/libpthread.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=73954, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f91000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0X<\0\000"..., 4096) = 4096
mmap2(NULL, 73728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f7c000
mmap2(0xb7f7c000, 37024, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xb7f7c000
mmap2(0xb7f86000, 21704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x9) = 0xb7f86000
mmap2(0xb7f8c000, 5760, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f8c000
close(3) = 0
munmap(0xb7f91000, 4096) = 0
open("/lib/libm.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=41616, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f91000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\21\0"..., 4096) = 4096
mmap2(NULL, 49152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f70000
mmap2(0xb7f70000, 37732, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xb7f70000
mmap2(0xb7f7a000, 4100, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x9) = 0xb7f7a000
close(3) = 0
munmap(0xb7f91000, 4096) = 0
open("/lib/libc.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=268884, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f91000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360\250"..., 4096) = 4096
mmap2(NULL, 290816, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f29000
mmap2(0xb7f29000, 262416, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xb7f29000
mmap2(0xb7f6a000, 5148, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x40) = 0xb7f6a000
mmap2(0xb7f6c000, 15996, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f6c000
close(3) = 0
munmap(0xb7f91000, 4096) = 0
open("/lib/libc.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=268884, ...}) = 0
close(3) = 0
open("/lib/libc.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=268884, ...}) = 0
close(3) = 0
open("/lib/libc.so.0", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=268884, ...}) = 0
close(3) = 0
munmap(0xb7f92000, 3664) = 0
stat("/lib/ld-uClibc.so.0", {st_mode=S_IFREG|0755, st_size=17000, ...}) = 0
mprotect(0xb7f90000, 4096, PROT_READ) = 0
mprotect(0xb7f86000, 4096, PROT_READ) = 0
mprotect(0xb7f7a000, 4096, PROT_READ) = 0
mprotect(0xb7f6a000, 4096, PROT_READ) = 0
mprotect(0xb7f98000, 4096, PROT_READ) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
getpid() = 10573
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
setrlimit(RLIMIT_STACK, {rlim_cur=2040*1024, rlim_max=RLIM_INFINITY}) = 0
rt_sigaction(SIGRTMIN, {0xb7f84e7a, [], SA_RESTORER, 0xb7f33948}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0xb7f84de5, [RTMIN], SA_RESTORER, 0xb7f33948}, NULL, 8) = 0
rt_sigaction(SIGRT_2, {0xb7f8451a, [], SA_RESTORER, 0xb7f33948}, NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [RTMIN], NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1], NULL, 8) = 0
brk(0) = 0x817a000
brk(0x817b000) = 0x817b000
geteuid32() = 0
uname({sys="Linux", node="test", ...}) = 0
getpid() = 10573
stat64(0xbfce879c, 0xbfce60d0) = 0
open("/etc/asterisk/asterisk.conf", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfce605c) = -1 ENOTTY (Inappropriate ioctl for device)
brk(0x817c000) = 0x817c000
read(3, "[options]\nnocolor=yes\nastetcdir "..., 4096) = 594
read(3, "", 4096) = 0
close(3) = 0
sched_setscheduler(0, SCHED_OTHER, { 0 }) = 0
geteuid32() = 0
stat64(0xbfce878c, 0xbfce60c0) = -1 ENOENT (No such file or directory)
socket(PF_FILE, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_FILE, path="/var/run/asterisk.ctl"}, 110) = -1 ENOENT (No such file or directory)
close(3) = 0
unlink("/var/run/asterisk.pid") = 0
open("/var/run/asterisk.pid", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfce8acc) = -1 ENOTTY (Inappropriate ioctl for device)
getpid() = 10573
write(3, "10573\n", 6) = 6
close(3) = 0
write(1, "********** Have working fork ***"..., 42********** Have working fork ************
) = 42
fork(Process 10574 attached
) = 10574
[pid 10573] _exit(0) = ?
Process 10573 detached
setsid() = 10574
fork(Process 10575 attached
) = 10575
[pid 10574] _exit(0) = ?
Process 10574 detached
open("/dev/null", O_RDWR) = 3
dup2(3, 0) = 0
dup2(3, 1) = 1
dup2(3, 2) = 2
close(3) = 0
getpid() = 10575
unlink("/var/run/asterisk.pid") = 0
open("/var/run/asterisk.pid", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfce8acc) = -1 ENOTTY (Inappropriate ioctl for device)
write(3, "10575\n", 6) = 6
close(3) = 0
write(1, "Test recursive mutex locking\n", 29) = 29
write(1, "Test for thread safety called\n", 30) = 30
write(1, "First lock\n", 11) = 11
write(1, "Pthread create\n", 15) = 15
ioctl(2147483647, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfce89a0) = -1 EBADF (Bad file descriptor)
brk(0x817d000) = 0x817d000
brk(0x817e000) = 0x817e000
pipe([3, 4]) = 0
clone(Process 10576 attached
child_stack=0x817dad4, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND) = 10576
[pid 10575] write(4, "\324\256\366\267\5\0\0\0\300\211\316\277\245H\366\267\24"..., 148) = 148
[pid 10575] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid 10575] write(4, "@\260\370\267\0\0\0\0\20\213\316\277\320\211\16\10\240"..., 148) = 148
[pid 10575] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid 10575] rt_sigsuspend([] <unfinished ...>
[pid 10576] rt_sigprocmask(SIG_SETMASK, ~[TRAP RT_1], NULL, 8) = 0
[pid 10576] read(3, "\324\256\366\267\5\0\0\0\300\211\316\277\245H\366\267\24"..., 148) = 148
[pid 10576] poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 2000) = 1
[pid 10576] getppid() = 10575
[pid 10576] read(3, "@\260\370\267\0\0\0\0\20\213\316\277\320\211\16\10\240"..., 148) = 148
[pid 10576] old_mmap(0xbf5fc000, 16384, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0) = 0xbf5fc000
[pid 10576] old_mmap(0xbf5c3000, 4096, PROT_NONE, MAP_FILE|MAP_FIXED, -1, 0) = -1 EBADF (Bad file descriptor)
[pid 10576] sched_getscheduler(10573) = -1 ESRCH (No such process)
[pid 10576] sched_getparam(10573, { 0 }) = -1 ESRCH (No such process)
[pid 10576] clone(Process 10577 attached
child_stack=0xbf5ffe04, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGRT_1) = 10577
[pid 10576] kill(10573, SIGRTMIN) = -1 ESRCH (No such process)
[pid 10576] poll( <unfinished ...>
[pid 10577] getpid() = 10577
[pid 10577] rt_sigprocmask(SIG_SETMASK, [RTMIN], NULL, 8) = 0
[pid 10577] write(1, "Test thread body started\n", 25) = 25
[pid 10577] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid 10577] rt_sigsuspend([] <unfinished ...>
[pid 10576] <... poll resumed> [{fd=3, events=POLLIN}], 1, 2000) = 0
[pid 10576] getppid() = 10575
[pid 10576] poll([{fd=3, events=POLLIN}], 1, 2000) = 0
[pid 10576] getppid() = 10575
[pid 10576] poll([{fd=3, events=POLLIN}], 1, 2000) = 0
[pid 10576] getppid() = 10575
[pid 10576] poll([{fd=3, events=POLLIN}], 1, 2000) = 0
[pid 10576] getppid() = 10575
[pid 10576] poll( <unfinished ...>
Process 10575 detached
Process 10576 detached
Process 10577 detached
#
# killall asterisk
# killall asterisk
killall: asterisk: no process killed



Attached Files  uClibc.config [^] (5,039 bytes) 12-15-07 15:02
 asterisk.c.diff [^] (1,124 bytes) 09-21-08 05:12
 asterisk.c_2.diff [^] (1,125 bytes) 09-21-08 05:42

- Relationships

- Notes
(0003179)
hwstar
12-15-07 17:44

I forgot to mention that this is only an issue with asterisk when it is run as a daemon. Running it in the foreground works as expected. It seems that running it as a daemon affects the operation of the thread library, because if I comment out the thread safe test, the code will run until it executes ast_pthread_create_background then it never returns.
 
(0011784)
spblinux
09-21-08 05:11
edited on: 09-21-08 05:43

Same issue with mipsel architecture. - But if the call to daemon() inside asterisk.c: main() is removed or replaced by the code found in uClibc-0.9.29/libc/unistd/daemon.c (see attached patch asterisk.c_2.diff) the error disappears.

It seems to make a difference if fork() is called inside the main() function or inside a uClibc library function (that is inside daemon() routine). - In the situation described above daemon() returns with 0, but recursive mutex locking fails.

edit: patch asterisk.c_2.diff is valid (not asterisk.c.diff)

 

- Issue History
Date Modified Username Field Change
12-15-07 15:02 hwstar New Issue
12-15-07 15:02 hwstar Status new => assigned
12-15-07 15:02 hwstar Assigned To  => buildroot
12-15-07 15:02 hwstar File Added: uClibc.config
12-15-07 15:02 hwstar Issue Monitored: hwstar
12-15-07 17:44 hwstar Note Added: 0003179
09-21-08 05:11 spblinux Note Added: 0011784
09-21-08 05:12 spblinux File Added: asterisk.c.diff
09-21-08 05:13 spblinux Note Edited: 0011784
09-21-08 05:13 spblinux Note Edited: 0011784
09-21-08 05:42 spblinux File Added: asterisk.c_2.diff
09-21-08 05:43 spblinux Note Edited: 0011784


Copyright © 2000 - 2006 Mantis Group
Powered by Mantis Bugtracker