Сегфо в pthreads на MIPS - PullRequest
0 голосов
/ 03 июля 2018

Я пытаюсь запустить свой код на компьютере с MIPS Linux (с прямым порядком байтов, без аппаратных переменных):

# cat /proc/cpuinfo | grep model
cpu model               : MIPS 24Kc V5.5

Моя программа хорошо работает в системах x86 и ARM, но дает сбой из-за ошибки сегментации в MIPS, всегда в (или почти) pthreads вызовах библиотечных функций. Я пробовал две цепочки инструментов (MTI GNU / Linux Toolchain MIPS32R2-MIPS32R5 от здесь и Sourcery CodeBench Lite 2016.05-8 от здесь ) - детали немного отличаются, но всегда возникает ошибка.

Чтение списков рассылки. Я обнаружил две причины pthreads ошибок сегментации на платформе MIPS:

  • возможно, неправильная реализация pthread_unlock_mutex() и pthread_wait_cond() в MIPS-версии uClibc. Но я использую glibc (хотя ОС на устройстве основана на uClibc);
  • проблема динамической загрузки библиотеки в pthreads; но моя программа статически связана.

Я написал очень простую программу:

#include <chrono>
#include <iostream>
#include <thread>

using namespace std;

void sayHello() {
    this_thread::sleep_for(chrono::seconds(2));
    cout << "Hello world!" << endl;
}

int main(int argc, char* argv[]) {
    thread t(sayHello);
    t.join();
    return 0;
}

Сбой на MIPS тоже. В отладчике с точкой останова на t.join() вижу следующее:

(gdb) c
Continuing.

Breakpoint 1, __start () at ../sysdeps/mips/start.S:84
84      in ../sysdeps/mips/start.S
(gdb) disassemble 
Dump of assembler code for function __start:
   0x004059b0 <+0>:     lui     gp,0x5b
   0x004059b4 <+4>:     addiu   gp,gp,-30464
=> 0x004059b8 <+8>:     move    ra,zero
   0x004059bc <+12>:    lui     a0,0x40
   0x004059c0 <+16>:    addiu   a0,a0,21584
   0x004059c4 <+20>:    lw      a1,0(sp)
   0x004059c8 <+24>:    addiu   a2,sp,4
   0x004059cc <+28>:    li      at,-8
   0x004059d0 <+32>:    and     sp,sp,at
   0x004059d4 <+36>:    addiu   sp,sp,-32
   0x004059d8 <+40>:    lui     a3,0x4d
   0x004059dc <+44>:    addiu   a3,a3,-208
   0x004059e0 <+48>:    lui     t0,0x4d
   0x004059e4 <+52>:    addiu   t0,t0,4
   0x004059e8 <+56>:    sw      t0,16(sp)
   0x004059ec <+60>:    sw      v0,20(sp)
   0x004059f0 <+64>:    jal     0x4cf8a0 <__libc_start_main>
   0x004059f4 <+68>:    sw      sp,24(sp)
End of assembler dump.
… (some boring "n"-s here) …
(gdb) n
109     in ../sysdeps/mips/start.S
(gdb) disassemble 
Dump of assembler code for function __start:
   0x004059b0 <+0>:     lui     gp,0x5b
   0x004059b4 <+4>:     addiu   gp,gp,-30464
   0x004059b8 <+8>:     move    ra,zero
   0x004059bc <+12>:    lui     a0,0x40
   0x004059c0 <+16>:    addiu   a0,a0,21584
   0x004059c4 <+20>:    lw      a1,0(sp)
   0x004059c8 <+24>:    addiu   a2,sp,4
   0x004059cc <+28>:    li      at,-8
   0x004059d0 <+32>:    and     sp,sp,at
   0x004059d4 <+36>:    addiu   sp,sp,-32
   0x004059d8 <+40>:    lui     a3,0x4d
   0x004059dc <+44>:    addiu   a3,a3,-208
   0x004059e0 <+48>:    lui     t0,0x4d
   0x004059e4 <+52>:    addiu   t0,t0,4
   0x004059e8 <+56>:    sw      t0,16(sp)
   0x004059ec <+60>:    sw      v0,20(sp)
=> 0x004059f0 <+64>:    jal     0x4cf8a0 <__libc_start_main>
   0x004059f4 <+68>:    sw      sp,24(sp)
End of assembler dump.
(gdb) n
[New Thread 29775]

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) info registers 
          zero       at       v0       v1       a0       a1       a2       a3
 R0   00000000 00000000 00000016 005af490 2bc7d310 00000000 2bc7d378 00000000 
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   00000000 00000000 00000000 82ee2000 00000000 00000000 00000001 74697773 
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  7fbbf194 004450c4 00464200 004641f0 00460000 2b929478 0045742c 00000001 
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  00000000 00000000 2bc847a0 00000000 005a8900 7fbbf158 7f894280 0041bd54 
        status       lo       hi badvaddr    cause       pc
      0100ff13 3b9aca00 00000000 00000000 50800008 00000000 
          fcsr      fir      hi1      lo1      hi2      lo2      hi3      lo3
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
        dspctl  restart
      00000000 00000000

Пример программы без потоков работает хорошо.

Что я могу сделать сейчас? Кто-нибудь похожий опыт с pthreads на MIPS?

1 Ответ

0 голосов
/ 04 июля 2018

Отвечая на мой вопрос.

Эрик Алапяа был прав, сборка с помощью uClibc решила эту проблему. Я до сих пор не могу понять, почему (программа статически связана).

Кстати: я использовал glibc, потому что не смог собрать Boost.Asio с uClibc - pthreads библиотека, созданная с помощью uClibc из моего набора инструментов, не содержит функции pthread_condattr_setclock(). Исправлено с помощью следующего патча для Boost.Asio:

diff --git a/include/boost/asio/detail/impl/posix_event.ipp b/include/boost/asio/detail/impl/posix_event.ipp
index 4ff246f3..04f87a3a 100644
--- a/include/boost/asio/detail/impl/posix_event.ipp
+++ b/include/boost/asio/detail/impl/posix_event.ipp
@@ -33,10 +33,12 @@ posix_event::posix_event()
   : state_(0)
 {
 #if (defined(__MACH__) && defined(__APPLE__)) \
-      || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
+      || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) \
+      || (defined(__UCLIBC__))
   int error = ::pthread_cond_init(&cond_, 0);
 #else // (defined(__MACH__) && defined(__APPLE__))
       // || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
+      // || (defined(__UCLIBC__))
   ::pthread_condattr_t attr;
   ::pthread_condattr_init(&attr);
   int error = ::pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
@@ -44,7 +46,7 @@ posix_event::posix_event()
     error = ::pthread_cond_init(&cond_, &attr);
 #endif // (defined(__MACH__) && defined(__APPLE__))
        // || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
-
+       // || (defined(__UCLIBC__))
   boost::system::error_code ec(error,
       boost::asio::error::get_system_category());
   boost::asio::detail::throw_error(ec, "event");

Ну, это вроде клуджа, но это работает.

...