#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. К сожалению, проблема не в этом.