Проблема
Я пытаюсь обернуть старый код C в пакет R.
До сих пор мне удалось заставить RStudio скомпилировать код, экспортировать функцию, и все в теле функции выполняется должным образом вплоть до конца выполнения.
Затем Rsession прерывается без сообщения об ошибке (кроме кнопок перезапуска сеанса).
Мой вопрос: Почему? и как я могу это исправить?
РЕДАКТИРОВАТЬ: я нашел способ заставить его работать, это в конце этого поста, но я до сих пор без ответов на оба вопроса.
Кодовые биты
Оболочка выглядит так:
#' @useDynLib mypackage main_
#' @export
cellid <- function(args) {
# Example input:
# args <- "cell -p ~/Projects/Colman/HD/scripts/cellMagick/data/images/parameters.txt -b /tmp/Rtmp7fjlFo/file2b401093d715 -f /tmp/Rtmp7fjlFo/file2b402742f6ef -o ~/Projects/Colman/HD/uscope/20200130_screen_act1_yfp/1/Position001/out"
argv <- strsplit(args, " ")[[1]] # Split arguments
argc <- length(argv) # Get length
.C(main_, as.integer(argc), as.character(argv))
}
Фактическая функция выглядит так:
int main_(int* aargc, char* argv[]){
... DO A LOT OF STUFF ...
return 1;
}
То, что я пробовал
Как я уже говорил, если я go ищу эффекты функции на ожидаемые системные файлы, я нахожу там все. Единственный способ предотвратить сбой Rsession - это выдать ошибку перед возвратом:
int main_(int* argc, char* argv[]){
... DO A LOT OF STUFF ...
error("everything works up to this point");
return 1;
}
Я пробовал много вещей совершенно слепо. Например, изменение int на void в определении функции и пропуск оператора return не помогает.
Я использовал lldb, как предлагалось здесь , и из него получил следующее:
Process 7900 stopped
* thread #1, name = 'R', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
frame #0: 0x00007ffff7a946f5 libc.so.6`__strlen_avx2 + 21
libc.so.6`__strlen_avx2:
-> 0x7ffff7a946f5 <+21>: vpcmpeqb (%rdi), %ymm0, %ymm1
0x7ffff7a946f9 <+25>: vpmovmskb %ymm1, %eax
0x7ffff7a946fd <+29>: testl %eax, %eax
0x7ffff7a946ff <+31>: jne 0x7ffff7a947f0 ; <+272>
Что я не могу интерпретировать, мои C навыки в основном равны нулю.
Сужая причину
Мне удалось только сузить проблему до та часть, в которой заканчивается функция C, и R должен продолжаться (я полагаю).
Возможно, проблема в объектах-указателях (argv
и argc
). Я заметил, что argc
и argv
меняют свое содержимое во время выполнения функции (т.е. они сокращены, см. Ниже).
В начале функции:
Input argument number (argc[0]): 9
Input argument (argv[i] for printf): cell -p ~/Projects/Colman/HD/scripts/cellMagick/data/images/parameters.txt -b /tmp/Rtmplr4Q90/file26f12a94a144 -f /tmp/Rtmplr4Q90/file26f175cd02e5 -o ~/Projects/Colman/HD/uscope/20200130_screen_act1_yfp/1/Position001/out
В конце функции:
Input argument number (argc[0]): 1
Input argument (argv[i] for printf): cell
Хотя я не уверен, может ли это быть проблемой, этот побочный эффект обычно вызывается g_option_context_parse glib для анализа аргументов.
Подозрительно для меня, комментирование всего после строки g_option_context_parse
все еще вызывает segfault, но комментирование этой строки и всего после того, как это не вызывает segfault.
Is R ожидает найти arg c и argv без изменений? Будет ли это sh, когда этого не произойдет?
К сожалению, это насколько я смог сделать самостоятельно.
Я пытался сохранить этот вопрос Короче, но полный источник C программы доступен (main
определен в cell.c
).
Буду признателен за вашу помощь. Дайте мне знать, как я могу улучшить свой вопрос, если это поможет.