execvp call en la fuente de git para cmd de shell externo devuelve EFAULT (Bad address) errno, aparentemente solo en 64 bit. Google no revela nada

ACTUALIZACIÓN: ejecutando git diff con valgrind resultados en

Syscall param execve(argv) points to uninitialised byte(s) 

Y la salida de strace no está totalmente decodificada, es decir, hay numbers hexadecimales entre la matriz de cadenas que es argv.

Esto comenzó como un problema de superusuario, pero definitivamente se movió al dominio de SO ahora.

Pero de todos modos, aquí está mi publicación original de SU que detalla el problema antes de ver mucho la fuente: https://superuser.com/questions/795751/various-methods-of-trying-to-set-up-a-git -diff-tool-lead-to-fatal-can-exec

Esencialmente, seguir el procedimiento estándar para configurar vimdiff como una herramienta de diff estableciendo la directiva externa bajo [diff] en .gitconfig conduce a este error de esta manera:

 fatal: cannot exec 'git_diff_wrapper': Bad address external diff died, stopping at HEAD:switch-monitor.sh. 

Sucede en mi sistema operativo Linux Mint 17 de 64 bits, así como en un sistema operativo Ubuntu 14.04 de 64 bits en una máquina virtual virtualbox, pero no en una máquina virtual Ubuntu 14.04 de 32 bits

Google no revela problemas similares. He pasado mucho time mirando la fuente de git para resolver esto. La dirección incorrecta es la descripción devuelta por strerror para un error EFAULT . Aquí hay una breve descripción de EFAULT de la EFAULT de EFAULT de execve:

 EFAULT filename points outside your accessible address space 

He rastreado cómo git ensambló el post de error y lo he usado para networkingucir un poco el origen del problema. Comencemos aquí:

 static int execv_shell_cmd(const char **argv) { const char **nargv = prepare_shell_cmd(argv); trace_argv_printf(nargv, "trace: exec:"); sane_execvp(nargv[0], (char **)nargv); free(nargv); return -1; } 

Esta function no debe devolver el control, pero lo hace debido al error. La llamada real de execvp está en sane_execvp , pero quizás prepare_shell_cmd sea ​​de interés, aunque no veo ningún problema:

 static const char **prepare_shell_cmd(const char **argv) { int argc, nargc = 0; const char **nargv; for (argc = 0; argv[argc]; argc++) ; /* just counting */ /* +1 for NULL, +3 for "sh -c" plus extra $0 */ nargv = xmalloc(sizeof(*nargv) * (argc + 1 + 3)); if (argc < 1) die("BUG: shell command is empty"); if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) { #ifndef GIT_WINDOWS_NATIVE nargv[nargc++] = SHELL_PATH; #else nargv[nargc++] = "sh"; #endif nargv[nargc++] = "-c"; if (argc < 2) nargv[nargc++] = argv[0]; else { struct strbuf arg0 = STRBUF_INIT; strbuf_addf(&arg0, "%s \"$@\"", argv[0]); nargv[nargc++] = strbuf_detach(&arg0, NULL); } } for (argc = 0; argv[argc]; argc++) nargv[nargc++] = argv[argc]; nargv[nargc] = NULL; return nargv; } 

No parece que hayan estropeado el puntero NULL de terminación (cuya ausencia se sabe que causa EFAULT).

sane_execvp es bastante sencillo. Es una llamada a execvp y devuelve -1 si falla.

No he descubierto lo que trace_argv_printf hace, aunque parece que podría afectar nargv y tal vez nargv el puntero NULL de terminación. Si quieres que lo incluya en esta publicación, házmelo saber.

Hasta ahora no he podido reproducir un EFAULT con execvp en mi propio código C.

Esto es git 1.9.1, y el código fuente está disponible aquí: https://www.kernel.org/pub/software/scm/git/git-1.9.1.tar.gz

¿Alguna idea sobre cómo avanzar?

Gracias

Respuesta (copyda de los comentarios): parece ser un error en git 1.9.1. El (antiguo) código diff.c , alnetworkingedor de la línea 2910-2930, completa una matriz de tamaño 10 con arguments antes de llamar al código de ejecución de command. Pero en un caso pone diez arguments reales y luego un 11 ° NULL . Dependiendo de los caprichos del comstackdor, el NULL puede sobreescribirse con alguna otra variable local (o el NULL puede sobreescribir algo importante).

Cambiar la matriz al tamaño 11 debería solucionar el problema. O simplemente actualice a un git más nuevo (v2.0.0 o posterior); Jeff King reemplazó la matriz codificada con una dinámica, en commits 82fbf269b9994d172719b2d456db5ef8453b323d y ae049c955c8858899467f6c5c0259c48a5294385 .