[asterisk-dev] [Fwd: Asterisk 1.4.15 and uClibc 0,9.29]

Stephen Rodgers hwstar at rodgers.sdcoxmail.com
Sun Dec 16 16:10:16 CST 2007



-------- Original Message --------
From: - Sun Dec 16 14:08:37 2007
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00800000
Message-ID: <4765A1E5.4040507 at rodgers.sdcoxmail.com>
Date: Sun, 16 Dec 2007 14:08:37 -0800
From: Stephen Rodgers <hwstar at rodgers.sdcoxmail.com>
User-Agent: Thunderbird 1.5.0.14pre (X11/20071023)
MIME-Version: 1.0
To: asterisk-dev at lists.digium.com
Subject: Asterisk 1.4.15 and uClibc 0,9.29
X-Enigmail-Version: 0.94.2.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

I've been partially successful in getting Asterisk 1.4.15 to run with
uClibc 0.9.29 on a buildroot linux system with the develooment tools
present on the target system. Asterisk will run just fine when not
running as a daemon. As soon as you tell it to run as a daemon,
asterisk.ctl does not get created. Tracking this down with strace shows:

> # 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



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 returns causing
asterisk.ctl
to never be created.

The strace dump shows that the test thread is being created, and from
within the test thread,
the system never returns from the lock right after the debug message
"Test thread body started\n".

In the main process code, nothing happens after the the call to
ast_pthread_create() withing the function test_for_thread_safety().

I put extra printf statments in test_for_thread_safety() and the test
thread to located the call to ast_pthread_create which was failing
above. Here is the modified 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;
}


This could very well be an issue with uClibC 0.9.29, But what I don't
quite understand is why it works when run and the foreground and does
not when run in the background. How would running in the background
affect pthreads?

Thanks
Steve Rodgers







More information about the asterisk-dev mailing list