inux32bit thosttraderapi.so 加载错误

Discussion in 'CTP' started by 白云传说, Jun 24, 2015.

  1. linux32bit trader运行加载thosttraderapi.so出错 SIGSEGV, Segmentation fault

    最近把win上跑的ctp接口挪到linux32上 行情md可以跑,一切正常. 交易trader就运行错误, gdb后发现是thosttraderapi.so在程序加载时内部调用了0xb7b9e4ce in OPENSSL_cpuid_setup (). 出现Segmentaion fault

    我折腾了一个月还是没得头绪,系统是32位的 gentoo 和 centos 6都试过, thosttraderapi.so 版本用过2010年的,还有2014年的v6.3.6都是同样的问题.现在行情在linux上跑,下单在vista上跑, 一直不爽.
     
  2. 看来没人碰到这个问题, objdump -S -d thosttraderapi.so 先把反汇编列一下.

    000864ec <_init>:
    864ec: 55 push %ebp
    864ed: 89 e5 mov %esp,%ebp
    864ef: 83 ec 08 sub $0x8,%esp
    864f2: e8 89 46 00 00 call 8ab80 <call_gmon_start>
    864f7: e8 34 47 00 00 call 8ac30 <frame_dummy>
    864fc: e8 bf af 0f 00 call 1814c0 <OPENSSL_cpuid_setup>
    86501: e8 8a df 1b 00 call 244490 <__do_global_ctors_aux>
    86506: c9 leave
    86507: c3 ret


    init 之后就直接 call OPENSSL_cpuid_setup,跑到 001814c0 对应内容如下.

    001814c0 <OPENSSL_cpuid_setup>:
    1814c0: 48 dec %eax
    1814c1: 89 5c 24 f0 mov %ebx,-0x10(%esp)
    1814c5: 48 dec %eax
    1814c6: 89 6c 24 f8 mov %ebp,-0x8(%esp)
    1814ca: 48 dec %eax
    1814cb: 83 ec 28 sub $0x28,%esp
    1814ce: 8b 05 d8 80 39 00 mov 0x3980d8,%eax (出错位置)
    1814d4: 85 c0 test %eax,%eax
    1814d6: 74 0f je 1814e7 <OPENSSL_cpuid_setup+0x27>
    1814d8: 48 dec %eax
    1814d9: 8b 5c 24 18 mov 0x18(%esp),%ebx
    1814dd: 48 dec %eax
    ... ...后面不列。

    再用gdb调试,在OPENSSL_cpuid_setup 前设置断点, 单步执行了7步出错. 如上标注, 以下为gdb输出。

    Breakpoint 1, 0xb7b9e4c0 in OPENSSL_cpuid_setup ()
    from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si
    0xb7b9e4c1 in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si
    0xb7b9e4c5 in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si
    0xb7b9e4c6 in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si
    0xb7b9e4ca in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si
    0xb7b9e4cb in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si
    0xb7b9e4ce in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    (gdb) si

    Program received signal SIGSEGV, Segmentation fault.
    0xb7b9e4ce in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
     
  3. 尝试一下午夜屠夫直接修改thosttraderapi.so文件控制跳转。

    先把反汇编AT&T格式换成intel格式.

    001814c0 <OPENSSL_cpuid_setup>:
    1814c0: 48 dec eax
    1814c1: 89 5c 24 f0 mov DWORD PTR [esp-0x10],ebx
    1814c5: 48 dec eax
    1814c6: 89 6c 24 f8 mov DWORD PTR [esp-0x8],ebp
    1814ca: 48 dec eax
    1814cb: 83 ec 28 sub esp,0x28
    1814ce: 8b 05 d8 80 39 00 mov eax,DWORD PTR ds:0x3980d8 (出错)
    1814d4: 85 c0 test eax,eax
    1814d6: 74 0f je 1814e7 <OPENSSL_cpuid_setup+0x27>
    1814d8: 48 dec eax
    1814d9: 8b 5c 24 18 mov ebx,DWORD PTR [esp+0x18]
    1814dd: 48 dec eax
    1814de: 8b 6c 24 20 mov ebp,DWORD PTR [esp+0x20]
    1814e2: 48 dec eax
    1814e3: 83 c4 28 add esp,0x28
    1814e6: c3 ret
    1814e7: 48 dec eax
    1814e8: 8d 3d 78 db 0c 00 lea edi,ds:0xcdb78
    1814ee: c7 05 b4 80 39 00 01 mov DWORD PTR ds:0x3980b4,0x1
    1814f5: 00 00 00

    这下好看多了,把 出错行的代码改成6个nop操作
    1814ce: 8b05d8803900 mov eax,DWORD PTR ds:0x3980d8
    在thosttraderapi.so文件类找
    1814c0: 48895C24F048896C24F84883EC288B05D8803900
    改成 1814c0: 48895C24F048896C24F84883EC28909090909090

    从新rebuild 运行,还是
    Program received signal SIGSEGV, Segmentation fault.
    0xb7b9e381 in CRYPTO_set_id_callback () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    在这里出错
    00181380 <CRYPTO_set_id_callback>:
    181380: 48 dec eax
    181381: 89 3d 49 82 39 00 mov DWORD PTR ds:0x398249,edi (出错)
    181387: c3 ret
    181388: 0f 1f 84 00 00 00 00 nop DWORD PTR [eax+eax*1+0x0]
    18138f: 00

    再把je 改成jne,不退出 跳到 1814e7 开始运行
    1814d0: 9090909085C0740F
    改成 1814d0: 9090909085C0750F


    Program received signal SIGSEGV, Segmentation fault.
    0xb7b9e4ee in OPENSSL_cpuid_setup () from /home/prog/ctp/td32_6.3.6/lib/thosttraderapi.so
    还是错
    1814ee: c7 05 b4 80 39 00 01 mov DWORD PTR ds:0x3980b4,0x1 (出错)

    看来所有错误都是指向 对DS区域的读写 DWORD PTR ds:0x398___ 怎么办?
     
  4. 据说官网提供下载的32位版本误链接了64位库导致运行时崩溃,请试下这个版本:http://itfin.f3322.org/pub/ctp32.7z,是我们要求CTP重新提供的,版本是6.3.0,略老一点。
     
  5. 上面提供的版本可以用了,我手上的版本不是64的问题,出错全是访问 DWORD PTR ds:0x398 的代码段,所在的函数都是openssl有关的。

    001812b0 <CRYPTO_get_dynlock_lock_callback>:
    001812e0 <CRYPTO_set_dynlock_lock_callback>:
    001812c0 <CRYPTO_get_dynlock_destroy_callback>:
    001812f0 <CRYPTO_set_dynlock_destroy_callback>
    00181310 <CRYPTO_get_add_lock_callback>:
    00181320 <CRYPTO_set_add_lock_callback>:
    00181330 <CRYPTO_THREADID_set_callback>:
    00181350 <CRYPTO_THREADID_get_callback>:
    00181370 <CRYPTO_get_id_callback>:
    00181380 <CRYPTO_set_id_callback>:
    001812d0 <CRYPTO_set_dynlock_create_callback>:
    00181300 <CRYPTO_get_locking_callback>:
    001814c0 <OPENSSL_cpuid_setup>:

    全都是和和OPENSSL有关的调用,在网上一个的crypto.h里面有定义,代码在cryptlib.c里面找到。
     
  6. 是不是调用SSL lib出错? 或者头文件和lib不匹配。
     
  7. 看so的依存关系,ssl应该是一起做到thosttraderapi.so里面了,没有再调用其他库, 目前用楼上提供的v6.3.0, 过几天闲下来再好好对比一下两个版本的看看能不能发现问题.

    ldd thosttraderapi.so
    linux-gate.so.1 (0xffffe000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb71c7000)
    librt.so.1 => /lib/librt.so.1 (0xb71be000)
    libdl.so.2 => /lib/libdl.so.2 (0xb71b9000)
    libstdc++.so.6 => /usr/lib/gcc/i686-pc-linux-gnu/4.8.4/libstdc++.so.6 (0xb70d1000)
    libm.so.6 => /lib/libm.so.6 (0xb708b000)
    libgcc_s.so.1 => /usr/lib/gcc/i686-pc-linux-gnu/4.8.4/libgcc_s.so.1 (0xb706e000)
    libc.so.6 => /lib/libc.so.6 (0xb6ed3000)
    /lib/ld-linux.so.2 (0xb7709000)
     
  8. 确实如itfin所说的,v6.3.0和v.6.3.6生成的时候连接的库不同,3.0里面OPENSSL调用和在3.6里面的程序内容也完全不一样,读写方式也不一样。
     
  9. 尝试把你的os改成64的吧
     
  10. 算了,我系统上还要升级mysql apache virtualbox R perl 一堆东西,我现在觉得能跑就不想换了,总结过去经验,我花在折腾系统和程序之间的配合的时间上远多于花在策略的开发和backtest上。