Возможная ошибка GCC с arm-wrs-linux-gnueabi - PullRequest
0 голосов
/ 11 июня 2019

Мне кажется, что я сталкиваюсь с ошибкой компилятора при создании очень большого проекта. Проблематичная генерация кода наблюдается только тогда, когда код компилируется с -O1 (а не с -O0 или -O2).

Проблема заключается в вызове функции, которая является оболочкой для find_if. Эта функция принимает в качестве входных данных пустой вектор, что должно привести к немедленному возвращению find_if.

Код выглядит примерно так:

void LookUpEvalResultFun(some arguments) {
  empty vector declaration
  some simple code handling the arguments
  call the function that is wrapper to find_if
}

В случае, если код не работает должным образом, ассемблер выглядит следующим образом:

0x00eab0dc <+0>:   strd r4, [sp, #-36]! ; 0xffffffdc
0x00eab0e0 <+4>:   strd r6, [sp, #8]
0x00eab0e4 <+8>:   strd r8, [sp, #16]
0x00eab0e8 <+12>:  strd r10, [sp, #24]
0x00eab0ec <+16>:  str  lr, [sp, #32]
0x00eab0f0 <+20>:  add  r11, sp, #32
0x00eab0f4 <+24>:  sub  sp, sp, #132    ; 0x84
0x00eab0f8 <+28>:  ldr  r3, [r0]
0x00eab0fc <+32>:  ldr  r3, [r3, #24]
0x00eab100 <+36>:  blx  r3
0x00eab104 <+40>:  movw r4, #21700 ; 0x54c4
0x00eab108 <+44>:  movt r4, #373   ; 0x175
0x00eab10c <+48>:  mov  r3, #0
0x00eab110 <+52>:  strb r3, [sp]
0x00eab114 <+56>:  ldr  r2, [r4, #52]   ; 0x34
0x00eab118 <+60>:  ldr  r0, [r4, #48]   ; 0x30
0x00eab11c <+64>:  bl   0xd9c4a0 <mangled name for find_if>

mangled name for find_if:
0x00d9c4a0 <+0>:   strd r4, [sp, #-32]! ; 0xffffffe0
0x00d9c4a4 <+4>:   strd r6, [sp, #8]
0x00d9c4a8 <+8>:   strd r8, [sp, #16]
0x00d9c4ac <+12>:  str  r11, [sp, #24]
0x00d9c4b0 <+16>:  str  lr, [sp, #28]
0x00d9c4b4 <+20>:  add  r11, sp, #28
0x00d9c4b8 <+24>:  mov  r9, r1
0x00d9c4bc <+28>:  mov  r7, r0
0x00d9c4c0 <+32>:  rsb  r8, r0, r1
0x00d9c4c4 <+36>:  asr  r8, r8, #6
0x00d9c4c8 <+40>:  movw r3, #43691 ; 0xaaab
0x00d9c4cc <+44>:  movt r3, #43690 ; 0xaaaa
0x00d9c4d0 <+48>:  mul  r8, r3, r8
0x00d9c4d4 <+52>:  asr  r8, r8, #2
0x00d9c4d8 <+56>:  cmp  r8, #0
0x00d9c4dc <+60>:  ble  0xd9c558 <_ZSt9__find_ifIN9__gnu_cxx17__normal_iterator...>

Инструкции ниже:

0x00eab114 <+56>:  ldr  r2, [r4, #52]   ; 0x34
0x00eab118 <+60>:  ldr  r0, [r4, #48]   ; 0x30

против

0x00d9c4b8 <+24>:  mov  r9, r1
0x00d9c4bc <+28>:  mov  r7, r0

показывает, что в функции-обертке R2 загружается vector.end (), а find_if ожидает найти vector.end () в R1.

Что более интересно, независимо от того, как код компилируется относительно уровней оптимизации, это следующее (при компиляции каждого файла отдельно с -c).

1244:   e3a00000    mov r0, #0
template<typename _Iterator, typename _Predicate>
inline _Iterator
__find_if(_Iterator __first, _Iterator __last, _Predicate __pred)
{
  return __find_if(__first, __last, __pred,                std::__iterator_category(__first));
1248:   e3a03000    mov r3, #0
124c:   e5cd3000    strb    r3, [sp]
1250:   e1a02000    mov r2, r0
1254:   ebfffffe    bl  0 <mangled name>
        1254: R_ARM_CALL    _ZSt9__find_ifIN9__gnu_cxx17__normal_iterator 

00000000 <mangled name>:
0:  e16d42f0    strd    r4, [sp, #-32]! ; 0xffffffe0
4:  e1cd60f8    strd    r6, [sp, #8]
8:  e1cd81f0    strd    r8, [sp, #16]
c:  e58db018    str fp, [sp, #24]
10: e58de01c    str lr, [sp, #28]
14: e28db01c    add fp, sp, #28
18: e1a09002    mov r9, r2
1c: e1a07000    mov r7, r0
20: e0608002    rsb r8, r0, r2
24: e1a08348    asr r8, r8, #6
28: e30a3aab    movw    r3, #43691  ; 0xaaab
2c: e34a3aaa    movt    r3, #43690  ; 0xaaaa

, который предполагает, что R2 используется правильно!

Мои теории примерно такие:

  1. Компилятор правильно компилирует каждый файл, и что-то происходит на следующих этапах.
  2. На самом деле есть ошибка компилятора, которая не отображается выводом objdump в конкретном файле, содержащем функцию-обертку.

Даже addr2line показывает что-то вроде этого:

0x00001254: _ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKN2ue7VariantINS2_12_...
(inlined by) _ZSt7find_ifIN9__gnu_cxx17__normal_iteratorIPKN2ue7VariantINS2_12_...
(inlined by) find_if wrapper
(inlined by) LookUpEvalResultFun at ...

что говорит о том, что objdump не лжет; что-то поддерживает первую теорию.

У вас есть идеи?

Спасибо.

...