ошибка выравнивания стека не по 16 байтам при издевательском выходе с помощью mimick

#c #macos #mocking #clang #llvm

Вопрос:

Я использую Mimick, чтобы имитировать функцию выхода, но я получаю ошибку стека, не выровненную по 16 байтам.

Вот сокращенный пример кода:

 #include <stdlib.h>
#include <mimick.h>

mmk_mock_define(exit_mock, void, int);

int main(void) {
  mmk_mock("exit@self", exit_mock);

  exit(EXIT_FAILURE);

  mmk_reset(exit);
  return 0;
}
 

Скомпилировано со следующим на macOS 11:
clang -I ./include -g -rpath ./lib/ -Wl,-segalign,1000 -L ./lib/ -l mimick -o test test.c
Где mimick уже скомпилирован и установлен в ./lib и ./include .

Бег с: lldb ./test

lldb дает мне:

 (lldb) target create "test"
Current executable set to '/Users/camdennarzt/Developer/C/test/test' (x86_64).
(lldb) r
Process 94625 launched: '/Users/camdennarzt/Developer/C/test/test' (x86_64)
Process 94625 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x00007fff20531c9e libdyld.dylib`stack_not_16_byte_aligned_error
libdyld.dylib`stack_not_16_byte_aligned_error:
->  0x7fff20531c9e < 0>: movdqa %xmm0, (%rsp)
    0x7fff20531ca3 < 5>: int3   
    0x7fff20531ca4 < 6>: nop    
    0x7fff20531ca5 < 7>: nop    
Target 0: (test) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x00007fff20531c9e libdyld.dylib`stack_not_16_byte_aligned_error
    frame #1: 0x00007ffeefbfefc8
    frame #2: 0x0000000100001941 test`mmk_mock_create_internal   289
    frame #3: 0x0000000100003315 test`mmkuser_exit_mock_create(tgt="x80amp;", opts=(sentinel_ = 0, noabort = 0)) at test.c:4:1
    frame #4: 0x00000001001ae010
    frame #5: 0x00007fff20532f3d libdyld.dylib`start   1
    frame #6: 0x00007fff20532f3d libdyld.dylib`start   1
 

Поскольку я видел это, я также попытался скомпилировать, -fno-stack-check -mmacosx-version-min=10.14 но это не помогло. Я также попробовал установить доморощенный лязг, но это тоже не помогло.

Что я здесь делаю не так? Или в библиотеке/компиляторе, который я использую, есть ошибка?

Ответ №1:

Я не знаю Критерия/Имитации, поэтому это может/может не иметь значения.

Если params[i].argv имитировать main() argv , то .argv[argc] как NULL отсутствует.

argv[argc] должен быть нулевой указатель.
Спецификация C17.

 params[0].argc = 1; 
params[0].argv = cr_malloc(sizeof(char*) * 2 /* not 1 */);
params[0].argv[0] = cr_strdup("progname"); 
params[0].argv[1] = NULL; /* add */
 

Аналогично для других params[i] и free_parse_args() нуждается в обновлении.

Комментарии:

1. К сожалению, проблема не в этом.