título del directorio
- Instalación de herramientas Valgrind
- Qué hace la herramienta Valgrind
- Herramienta de detección de fugas de memoria Memcheck
- Herramienta de detección de pilas de macizo
- Herramienta de análisis de rendimiento de Callgrind
- Precauciones
- Las herramientas no se pueden usar al mismo tiempo.
- epílogo
La pronunciación es [wɑːɡrɪnd].
Instalación de herramientas Valgrind
Valgrind es una herramienta de código abierto para la depuración de memoria, detección de fugas de memoria y análisis de rendimiento. Estos son los pasos para instalar Valgrind en Ubuntu u otros sistemas Debian:
- Abre una terminal.
- Primero, debe actualizar la lista de paquetes de su sistema. Se pueden utilizar los siguientes comandos:
sudo apt-get update
- Luego, instala Valgrind con el siguiente comando:
sudo apt-get install valgrind
- Una vez que se completa la instalación, puede verificar que Valgrind se instaló correctamente con el siguiente comando:
Si Valgrind se instaló correctamente, se mostrará el número de versión de Valgrind.valgrind --version
Para otras distribuciones de Linux como Fedora o CentOS, puede instalar Valgrind utilizando el administrador de paquetes correspondiente, como yum o dnf. Por ejemplo, en Fedora, puede instalar Valgrind con:
sudo dnf install valgrind
En macOS, puede usar Homebrew para instalar Valgrind:
brew install valgrind
Tenga en cuenta que es posible que Valgrind no admita versiones recientes de macOS.
En Windows, Valgrind no está disponible directamente, pero puede usarlo a través del Subsistema de Windows para Linux (WSL).
Compilación cruzada Valgrind
El código fuente de Valgrind incluye todas las bibliotecas que necesita para ejecutarse, por lo que en la mayoría de los casos puede compilar y ejecutar Valgrind sin dependencias adicionales. Sin embargo, se requieren algunas herramientas básicas de desarrollo para compilar Valgrind, incluido un compilador de C (como gcc) y la herramienta make.
Si planea realizar una compilación cruzada de Valgrind en una plataforma diferente, necesitará un compilador cruzado configurado para esa plataforma. También debe asegurarse de que su entorno de compilación incluya todos los encabezados y bibliotecas que necesita Valgrind.
Estos son los pasos básicos para realizar una compilación cruzada de Valgrind:
- Primero, descargue el código fuente de Valgrind. Puede descargar el código fuente más reciente del sitio web oficial de Valgrind: http://valgrind.org/downloads/current.html
- Descomprima el paquete del código fuente e ingrese al directorio del código fuente:
(Ajuste el número de versión en el comando anterior de acuerdo con la versión de Valgrind que descargó)tar xvf valgrind-3.17.0.tar.bz2 cd valgrind-3.17.0
- Configure el entorno de compilación. Debe especificar su compilador cruzado y la plataforma de destino. Por ejemplo, si su compilador cruzado es arm-linux-gnueabi-gcc y su plataforma de destino es arm-linux, puede usar el siguiente comando:
./configure --host=arm-linux CC=arm-linux-gnueabi-gcc
- Compilar Valgrind:
make
- Finalmente, puede copiar el Valgrind compilado en su sistema de destino o usar
make install
el comando para instalarlo en su entorno de compilación cruzada.
Tenga en cuenta que este es solo un ejemplo básico y es posible que deba ajustar estos pasos según sus necesidades específicas y su entorno de compilación cruzada.
Qué hace la herramienta Valgrind
Valgrind es una herramienta muy potente que se utiliza principalmente para la detección de errores en la gestión de la memoria y el análisis de la CPU y la memoria. Estos son algunos usos básicos:
-
detección de fugas de memoria
Esta es una de las características más utilizadas de Valgrind. Puede verificar si su programa tiene pérdidas de memoria con el siguiente comando:
valgrind --leak-check=yes your_program [your_program_arguments]
Esto ejecutará su programa e informará cualquier pérdida de memoria después de que finalice el programa.
--leak-check=yes
La opción le dice a Valgrind que verifique si hay pérdidas de memoria. -
Análisis de pila con Massif
Massif es una herramienta de Valgrind para analizar cuánta pila usa su programa. Puede ejecutar Massif con el siguiente comando:
valgrind --tool=massif your_program [your_program_arguments]
Esto generará un
massif.out.pid
archivo llamado , dondepid
está el ID de proceso de su programa. Puedems_print
ver el contenido de este archivo con el comando:ms_print massif.out.pid
-
Perfilado con Callgrind
Callgrind es una herramienta de Valgrind para perfilar el rendimiento de sus programas. Puede ejecutar Callgrind con el siguiente comando:
valgrind --tool=callgrind your_program [your_program_arguments]
Esto generará un
callgrind.out.pid
archivo llamado , dondepid
está el ID de proceso de su programa. Puedecallgrind_annotate
ver el contenido de este archivo con el comando:callgrind_annotate callgrind.out.pid
Los anteriores son solo algunos usos básicos de Valgrind. Valgrind tiene muchas otras funciones y opciones, puede consultar la documentación oficial de Valgrind para obtener más información: http://valgrind.org/docs/manual/index.html
Herramienta de detección de fugas de memoria Memcheck
Tenga en cuenta que debe asegurarse de que su programa y biblioteca dinámica estén -g
compilados con información de depuración (por ejemplo, usando la opción gcc), para que Valgrind pueda proporcionar informes más detallados.
Inspección de rutina (generar informe después de que finalice el programa)
La herramienta de detección de fugas de memoria de Valgrind, Memcheck, puede ser precisa en el número de línea del código fuente y decirle qué línea de código asignó memoria que no se liberó correctamente. Sin embargo, para poder hacer esto, debe incluir información de depuración al compilar su programa.
Si compiló su programa con GCC o Clang, puede agregar -g
la opción para incluir información de depuración:
gcc -g -o your_program your_program.c
Luego, puede ejecutar su programa con Valgrind:
valgrind --tool=memcheck --leak-check=full ./your_program
En los resultados informados, Valgrind mostrará la línea de código que provocó la pérdida de memoria. Por ejemplo:
==12345== 40 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x108671: main (your_program.c:2)
En este ejemplo, your_program.c:2
significa que la pérdida de memoria ocurre en la your_program.c
línea 2 del archivo.
Tenga en cuenta que algunas optimizaciones pueden hacer que la información del número de línea sea inexacta si su programa está compilado con opciones de optimización como -O2
o . -O3
Si es posible, debe compilar su programa sin optimización para la detección de fugas de memoria.
Parámetros importantes
-
--leak-check=yes
le indicará a Valgrind que realice una detección de fugas de memoria, pero solo proporcionará información agregada para cada punto de fuga, como la cantidad total de bytes filtrados y la cantidad de bloques filtrados. --leak-check=full
Se proporcionará información más detallada. Además de la información general sobre el punto de fuga, también muestra información sobre cada bloque filtrado individual, incluido su tamaño y el seguimiento de la pila de la función que lo asignó. Esto puede ayudarlo a identificar la ubicación de la pérdida de memoria con mayor precisión.--show-leak-kinds=all
Muestra todos los tipos de fugas de memoria, incluidos "definitivamente perdido", "perdido indirectamente", "posiblemente perdido" y "todavía accesible".--num-callers=n
Aumente la profundidad de la pila de llamadas.
--leak-check=full
Obtendrá una salida más detallada si usa :
==12345== 128 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x108671: func (your_program.c:4)
==12345== by 0x108687: main (your_program.c:8)
Esto muestra que la fuga de memoria está ocurriendo en la línea func
de la función , lo que puede ayudarlo a identificar el problema con mayor precisión.your_program.c:4
servicio de larga duracion
Valgrind informa por defecto de pérdidas de memoria y otros problemas al final del programa. Sin embargo, si su programa es un servicio de ejecución prolongada o si desea ver informes mientras se ejecuta, puede utilizar el modo gdbserver de Valgrind, que le permite interactuar con Valgrind en tiempo de ejecución.
Los siguientes son los pasos básicos para usar el modo gdbserver:
- Primero, inicie su programa, usando
--vgdb=yes
la opción para decirle a Valgrind que inicie gdbserver al inicio:valgrind --vgdb=yes --leak-check=full your_program [your_program_arguments]
- En otra terminal, puede usar gdb para conectarse a Valgrind. Primero, necesita encontrar el ID de proceso (PID) de su programa. Luego, conéctese a Valgrind con el siguiente comando:
Esto iniciará gdb y se conectará a Valgrind.gdb your_program (gdb) target remote | vgdb
- Ahora, puede usar el comando en gdb
monitor
para interactuar con Valgrind. Por ejemplo, puede usarmonitor leak_check full reachable any
el comando para verificar si hay pérdidas de memoria en tiempo de ejecución:
Esto le indicará a Valgrind que realice de inmediato una verificación completa de fugas de memoria e informe todas las fugas de memoria alcanzables e inaccesibles.(gdb) monitor leak_check full reachable any
Tenga en cuenta que este es solo un ejemplo básico y es posible que deba adaptar estos pasos a sus necesidades específicas. Puede consultar la documentación oficial de Valgrind para obtener más información sobre el modo gdbserver: http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
hacer la salida del informe a un archivo
De forma predeterminada, las fugas de memoria se enviarán directamente a la consola después del proceso, pero si
--show-leak-kinds=all
el parámetro está habilitado, el informe alcanzará decenas de miles de líneas y luego se debe enviar a un archivo.
Puede redirigir la salida de Valgrind a un archivo. >
Puede usar operadores en la línea de comando para hacer esto. Aquí hay un ejemplo:
valgrind --leak-check=full --show-leak-kinds=all your_program > output.txt
Este comando guardará la salida de Valgrind en output.txt
un archivo. Puede output.txt
reemplazar con cualquier nombre de archivo que desee.
Además, Valgrind proporciona una --log-file
opción que puede usar para especificar el archivo de salida. Aquí hay un ejemplo:
valgrind --leak-check=full --show-leak-kinds=all --log-file=output.txt your_program
Este comando tiene el mismo efecto que el comando anterior, que guarda la salida de Valgrind en output.txt
un archivo.
informe de análisis
ejemplo uno
==4197== LEAK SUMMARY:
==4197== definitely lost: 6,624 bytes in 2 blocks
==4197== indirectly lost: 0 bytes in 0 blocks
==4197== possibly lost: 12,864 bytes in 34 blocks
==4197== still reachable: 404,895,424 bytes in 504,849 blocks
==4197== of which reachable via heuristic:
==4197== multipleinheritance: 240 bytes in 1 blocks
==4197== suppressed: 0 bytes in 0 blocks
==4197== Reachable blocks (those to which a pointer was found) are not shown.
==4197== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4197==
==4197== For lists of detected and suppressed errors, rerun with: -s
==4197== ERROR SUMMARY: 32 errors from 32 contexts (suppressed: 0 from 0)
Análisis_Ejemplo 1
El siguiente es un análisis de este informe:
definitely lost: 6,624 bytes in 2 blocks
: Esto indica que 6624 bytes de memoria se perdieron de forma determinista en 2 bloques. Esto generalmente significa que la memoria ha sido asignada, pero no liberada, y el programa no puede volver a acceder a la memoria. Esta es una pérdida de memoria grave.indirectly lost: 0 bytes in 0 blocks
: Esto indica que no hay memoria perdida indirectamente. Memoria perdida indirectamente significa que los bloques de memoria perdidos directamente también se consideran perdidos porque contienen punteros a ellos.possibly lost: 12,864 bytes in 34 blocks
: Esto indica que se pueden perder 12864 bytes de memoria en 34 bloques. Memoria potencialmente perdida significa que la memoria aún puede estar en uso o puede haberse perdido.still reachable: 404,895,424 bytes in 504,849 blocks
: Esto significa que todavía se puede acceder a 404895424 bytes de memoria en 504849 bloques. Esta memoria no se libera cuando finaliza el programa, pero el programa aún puede acceder a ella si es necesario. Esto no es necesariamente un problema, pero si el número sigue creciendo, podría provocar una pérdida de memoria.suppressed: 0 bytes in 0 blocks
: Esto indica que no se suprimieron errores. Los errores suprimidos son aquellos que el usuario le ha dicho explícitamente a Valgrind que ignore.ERROR SUMMARY: 32 errors from 32 contexts
: Esto indica que Valgrind encontró 32 errores en 32 contextos diferentes.
Este informe indica que su programa puede tener una pérdida de memoria. Debe verificar su código, especialmente las partes que asignan y desasignan memoria, para asegurarse de que toda la memoria asignada se libere correctamente cuando termine de usarla.
Aquí hay algunas palabras clave en las que debe centrarse al revisar los informes:
- "definitivamente perdido": esto significa que la memoria se asignó pero no se liberó, y el programa no puede volver a acceder a ella. Esta es una pérdida de memoria grave.
- "posiblemente perdido": esto indica que la memoria aún puede estar en uso o puede haberse perdido. Esta situación suele ocurrir cuando el programa utiliza estructuras de datos complejas, como listas circulares enlazadas.
- "todavía accesible": esto significa que hay memoria que no se liberó al final del programa, pero el programa aún puede acceder a ella si es necesario. Esto no es necesariamente un problema, pero si el número sigue creciendo, podría provocar una pérdida de memoria.
- "perdida indirectamente": Esto significa que hay memoria porque los bloques de memoria perdidos directamente contenían punteros a esta memoria, por lo que la memoria también se considera perdida.
ejemplo dos
==4761== 320 bytes in 1 blocks are possibly lost in loss record 9,331 of 11,803
==4761== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4761== by 0x40147D9: calloc (rtld-malloc.h:44)
==4761== by 0x40147D9: allocate_dtv (dl-tls.c:375)
==4761== by 0x40147D9: _dl_allocate_tls (dl-tls.c:634)
==4761== by 0x4F08834: allocate_stack (allocatestack.c:430)
==4761== by 0x4F08834: pthread_create@@GLIBC_2.34 (pthread_create.c:647)
==4761== by 0xCEAF03A: zmq::thread_t::start(void (*)(void*), void*) (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE9FB3B: zmq::epoll_t::start() (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE8A35E: zmq::reaper_t::start() (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE7C833: zmq::ctx_t::create_socket(int) (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE7A2C5: zmq_socket (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE633EA: PubCANOutput::InitPub() (spi-service-protocol.h:33)
==4761== by 0xCE63A93: PubCANOutput::IpcCANOutputPub(unsigned char const*, int) (spi-service-protocol.h:65)
==4761== by 0xCE60F90: Send (spi-protocol-convert.h:22)
==4761== by 0xCE60F90: Send (protocol-convert-base.h:49)
==4761== by 0xCE60F90: HobotADAS::SPIProtocolConvert::OnMessageEnd(long const&, long const&) (spi-protocol-convert.cc:134)
==4761== by 0x2AE98C: HobotADAS::CommPluginManager::ProcessMsg() (comm_plugin_manager.cpp:321)
==4761==
==4761== 320 bytes in 1 blocks are possibly lost in loss record 9,332 of 11,803
==4761== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4761== by 0x40147D9: calloc (rtld-malloc.h:44)
==4761== by 0x40147D9: allocate_dtv (dl-tls.c:375)
==4761== by 0x40147D9: _dl_allocate_tls (dl-tls.c:634)
==4761== by 0x4F08834: allocate_stack (allocatestack.c:430)
==4761== by 0x4F08834: pthread_create@@GLIBC_2.34 (pthread_create.c:647)
==4761== by 0xCEAF03A: zmq::thread_t::start(void (*)(void*), void*) (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE9FB3B: zmq::epoll_t::start() (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE8281C: zmq::io_thread_t::start() (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE7C916: zmq::ctx_t::create_socket(int) (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE7A2C5: zmq_socket (in /home/lzy/work/acvite_code/test/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libspi-protocol-convert.so)
==4761== by 0xCE633EA: PubCANOutput::InitPub() (spi-service-protocol.h:33)
==4761== by 0xCE63A93: PubCANOutput::IpcCANOutputPub(unsigned char const*, int) (spi-service-protocol.h:65)
==4761== by 0xCE60F90: Send (spi-protocol-convert.h:22)
==4761== by 0xCE60F90: Send (protocol-convert-base.h:49)
==4761== by 0xCE60F90: HobotADAS::SPIProtocolConvert::OnMessageEnd(long const&, long const&) (spi-protocol-convert.cc:134)
==4761== by 0x2AE98C: HobotADAS::CommPluginManager::ProcessMsg() (comm_plugin_manager.cpp:321)
Análisis_Ejemplo 2
Este informe muestra posibles fugas de memoria que se producen en libspi-protocol-convert.so
determinadas llamadas a funciones en la biblioteca. Específicamente, estas funciones incluyen zmq::thread_t::start()
, zmq::epoll_t::start()
, zmq::reaper_t::start()
, zmq::ctx_t::create_socket()
, zmq_socket
, PubCANOutput::InitPub()
, PubCANOutput::IpcCANOutputPub()
y HobotADAS::SPIProtocolConvert::OnMessageEnd()
. Estas funciones pueden pasar o asignar memoria
durante la llamada , pero es posible que no liberen la memoria correctamente. Sin embargo, es importante tener en cuenta que estas fugas de memoria están marcadas como "posiblemente perdidas", lo que significa que Valgrind no puede determinar si estas fugas de memoria son realmente fugas. A veces, esto puede deberse a estrategias de gestión de memoria complejas o al comportamiento de funciones de biblioteca específicas (por ejemplo, ciertas funciones de subprocesos). Entonces, aunque los informes sugieren que puede haber una pérdida de memoria, no es definitivo. Es posible que deba examinar más a fondo su código, especialmente aquellas partes que involucran la asignación y desasignación de memoria, para determinar si realmente hay una pérdida de memoria.calloc
pthread_create@@GLIBC_2.34
libspi-protocol-convert.so
Herramienta de detección de pilas de macizo
Massif es una herramienta de Valgrind, que se utiliza principalmente para analizar el uso de la memoria del montón del programa durante la operación. Puede ayudar a los desarrolladores a descubrir el problema de que el programa consume demasiada memoria durante el proceso de ejecución, especialmente cuando la memoria se puede liberar normalmente después de que finaliza el programa, pero la memoria continúa creciendo durante el proceso de ejecución.
Uso básico de Massif
Puede ejecutar Massif con el siguiente comando:
valgrind --tool=massif your_program [your_program_arguments]
Esto generará un massif.out.pid
archivo llamado , donde pid
está el ID de proceso de su programa. Puede ms_print
ver el contenido de este archivo con el comando:
ms_print massif.out.pid
Esto le mostrará el uso de memoria de su programa mientras se está ejecutando. Puede consultar este informe para ver si hay picos inesperados en el uso de la memoria o si el uso de la memoria continúa aumentando con el tiempo.
Limitaciones del Macizo
Tenga en cuenta que Massif solo puede medir el uso de la memoria en montón, no la memoria de pila ni otros tipos de memoria. Si su programa tiene problemas con otros tipos de memoria, es posible que necesite usar otras herramientas o técnicas para detectarlo.
Uso avanzado de Massif
Aunque Massif puede proporcionar el uso de memoria general del programa, no puede decirle directamente qué módulo o qué pieza de código está solicitando memoria continuamente. Sin embargo, puede usar algunas opciones y herramientas adicionales para obtener información más detallada.
--alloc-fn
opción de uso
Si sabe qué función está asignando memoria (por ejemplo, si su módulo tiene una función de asignación de memoria específica), puede usar la --alloc-fn
opción para decirle a Massif que rastree las asignaciones de memoria para esta función:
valgrind --tool=massif --alloc-fn=my_alloc your_program [your_program_arguments]
Esto hará que Massif my_alloc
acredite toda la memoria asignada por la función a my_alloc
la persona que llama al .
--pages-as-heap
opción de uso
Esta opción hará que Massif trate todas las páginas de memoria como un montón, lo que le permite ver todas las asignaciones de memoria, no solo la memoria asignada por funciones malloc
, new
etc.:
valgrind --tool=massif --pages-as-heap=yes your_program [your_program_arguments]
Perfilado con Callgrind
Aunque Callgrind se usa principalmente para crear perfiles, también puede mostrar el uso de memoria por función. Puede usar Callgrind para ver qué función asigna la mayor cantidad de memoria:
valgrind --tool=callgrind your_program [your_program_arguments]
Luego puede usar kcachegrind
u otro visor de datos de Callgrind para ver los resultados.
Tenga en cuenta que estos métodos pueden requerir cierta comprensión de su código y sus patrones de uso de memoria. Esto puede ser difícil si su código es complejo o si utiliza muchas funciones de asignación de memoria diferentes.
vista del informe
Massif se diferencia de otras herramientas de detección de memoria en que genera un informe mientras se ejecuta el programa, en lugar de esperar a que finalice.
El informe de Massif es un archivo de texto generalmente llamado massif.out.pid
, donde pid
está el ID de proceso del programa en ejecución. Este archivo de informe contiene información detallada sobre el uso de la memoria del programa mientras se ejecuta.
Cada fila del informe representa un punto de muestreo, que muestra el uso de la memoria del montón del programa en ese momento. Cada punto de muestreo contiene la siguiente información:
- Tiempo: el tiempo desde el inicio del programa hasta el punto de muestreo.
- Uso de memoria: en este punto de muestreo, la cantidad total de memoria en montón utilizada por el programa.
- Rastreo de pila: en este punto de muestreo, la información de rastreo de pila del programa, que muestra qué llamadas de función conducen a la asignación de memoria.
Puede ms_print
ver y analizar este archivo de informe con el comando:
ms_print massif.out.pid
ms_print
formateará y enviará el contenido del archivo de informe a la consola, lo que facilitará su lectura y comprensión. La salida incluye un gráfico de uso de memoria y detalles para cada punto de muestreo.
Herramienta de análisis de rendimiento de Callgrind
La herramienta Callgrind de Valgrind se utiliza principalmente para recopilar información sobre el comportamiento del programa en tiempo de ejecución, incluido el número de llamadas a funciones, el número de lecturas de instrucciones, etc. Sin embargo, no mide directamente el tiempo de ejecución de una función. Si bien los recuentos de obtención de instrucciones y los recuentos de llamadas a funciones pueden proporcionar cierta información sobre el rendimiento del programa, no le dicen directamente qué funciones consumen mucho tiempo.
tiempos de lectura de comandos
"Extracciones de instrucciones" es una métrica que representa la cantidad de veces que se leyó (y posiblemente se ejecutó) una instrucción en una función particular durante la ejecución del programa. Esta métrica puede ayudarlo a comprender qué funciones se ejecutan con frecuencia en su programa.
Sin embargo, el número de búsquedas de instrucciones no es directamente igual al tiempo de ejecución de la función. Una función puede tener muchas instrucciones, pero si esas instrucciones se ejecutan rápidamente, el tiempo de ejecución de la función aún puede ser corto. Por otro lado, una función puede tener solo una pequeña cantidad de instrucciones, pero si esas instrucciones tardan mucho tiempo en ejecutarse (por ejemplo, si involucran E/S de disco o comunicación de red), entonces el tiempo de ejecución de la función puede ser muy largo. largo.
Por lo tanto, si bien los recuentos de obtención de instrucciones pueden proporcionar cierta información sobre el rendimiento de un programa, no le indica directamente qué funciones consumen mucho tiempo. Si desea conocer el tiempo de ejecución de una función, es posible que deba utilizar otras herramientas o técnicas de creación de perfiles, como un generador de perfiles de muestreo de CPU o un temporizador.
parámetros de uso
La herramienta Callgrind de Valgrind tiene muchas opciones que se pueden usar para personalizar su comportamiento y salida. Aquí hay algunas opciones que pueden funcionar para usted:
--dump-instr=yes
: Esta opción le indica a Callgrind que recopile información por instrucción, no solo información por función. Esto puede brindarle una comprensión más detallada del comportamiento de su programa, pero también hace que Callgrind se ejecute más lentamente y genere archivos de salida más grandes.--collect-jumps=yes
: Esta opción permite que Callgrind recopile información de saltos en el programa. Esto puede ayudarlo a comprender el flujo de control de su programa, pero también hace que Callgrind se ejecute más lentamente y genere archivos de salida más grandes.--branch-sim=yes
: Esta opción le dice a Callgrind que simule la predicción de bifurcación del programa. Esto puede ayudarlo a comprender la eficiencia de predicción de bifurcaciones de su programa, pero también hará que Callgrind se ejecute más lentamente.
Puede agregar estas opciones al ejecutar Callgrind, por ejemplo:
valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes your_program [your_program_arguments]
A continuación, puede utilizar callgrind_annotate
o kcachegrind
para ver los resultados. Estas herramientas pueden mostrar información detallada recopilada por Callgrind, incluida información por instrucción e información de salto.
Tenga en cuenta que estas opciones pueden hacer que Callgrind se ejecute más lentamente y produzca archivos de salida más grandes. Solo debe usar estas opciones cuando necesite estos detalles.
la generación del informe
Puede callgrind_annotate
redirigir la salida de a un archivo. En sistemas similares a Unix (como Linux o macOS), puede usar >
el símbolo para redirigir la salida. Por ejemplo:
callgrind_annotate callgrind.out.pid > output.txt
Esto escribirá callgrind_annotate
la salida en output.txt
el archivo en lugar de mostrarla en la terminal. Si output.txt
el archivo ya existe, este comando sobrescribirá su contenido; si el archivo no existe, este comando lo creará.
Si desea agregar la salida a un archivo existente en lugar de sobrescribirlo, puede usar >>
la notación:
callgrind_annotate callgrind.out.pid >> output.txt
Esto callgrind_annotate
agregará la salida de al output.txt
final del archivo.
Tenga en cuenta que es posible que estos comandos no funcionen desde el símbolo del sistema en los sistemas Windows. Si está ejecutando Valgrind en un sistema Windows (por ejemplo, a través de WSL o Cygwin), debe usar estos comandos en el entorno similar a Unix correspondiente.
Informe abierto de visualización
kcachegrind
y qcachegrind
son dos herramientas para visualizar datos de perfiles que pueden leer la salida generada por la herramienta Callgrind de Valgrind y generar gráficos de llamadas detallados.
Estos son los pasos básicos sobre cómo usar ambas herramientas:
- Generación de salida de Callgrind : Primero, debe usar la herramienta Callgrind para generar datos de perfil. Puede ejecutar su programa y generar la salida de Callgrind con el siguiente comando:
En este comando,valgrind --tool=callgrind your_program
your_program
se encuentra el programa que desea analizar. Este comando produce uncallgrind.out.pid
archivo llamado , dondepid
está el ID de proceso de su programa. - Instale kcachegrind o qcachegrind : luego, debe instalar
kcachegrind
oqcachegrind
. Puede instalar ambas herramientas a través de su administrador de paquetes. Por ejemplo, si está utilizando Ubuntu, puede instalarlo con el siguiente comandokcachegrind
:
Alternativamente, puede instalarlo con el siguiente comandosudo apt-get install kcachegrind
qcachegrind
:sudo apt-get install qcachegrind
- Activar la salida de Callgrind : finalmente, puede usar
kcachegrind
oqcachegrind
para activar la salida de Callgrind. Puede abrir el archivo con el siguiente comandocallgrind.out.pid
:
o:kcachegrind callgrind.out.pid
En ambos comandos,qcachegrind callgrind.out.pid
callgrind.out.pid
es el archivo de salida de Callgrind.
kcachegrind
y qcachegrind
mostrará un gráfico de llamadas detallado, que puede usar para ver los cuellos de botella de rendimiento de su programa. Puede hacer clic en los nodos del gráfico para ver información detallada de las llamadas, incluida la cantidad de llamadas, el tiempo de CPU consumido, etc.
Nota: No se pueden generar gráficos de llama
callgrind_annotate
La generación de gráficos de llamas no se admite de forma nativa. Un gráfico de llama es una herramienta de visualización para mostrar datos de perfil de un programa. Por lo general, se usan para mostrar el uso de la CPU, pero también se pueden usar para mostrar otros tipos de datos de rendimiento.
gprof2dot
Es una herramienta para generar gráficos de llamadas. Puede aceptar la salida de varias herramientas de análisis de rendimiento, incluidas gprof, oprofile, HProf, Xdebug, Visual Studio, VTune, etc., pero no puede analizar directamente la salida callgrind_annotate
.
informe de análisis
Ejemplo de fragmento de informe de análisis de rendimiento 1
--------------------------------------------------------------------------------
2 Profile data file 'callgrind.out.3896' (creator: callgrind-3.18.1)
3 --------------------------------------------------------------------------------
4 I1 cache:
5 D1 cache:
6 LL cache:
7 Timerange: Basic block 0 - 3688459443
8 Trigger: Program termination
9 Profiled target: ./comm_plugin_manager (PID 3896, part 1)
10 Events recorded: Ir
11 Events shown: Ir
12 Event sort order: Ir
13 Thresholds: 99
14 Include dirs:
15 User annotated:
16 Auto-annotation: on
17
18 --------------------------------------------------------------------------------
19 Ir
20 --------------------------------------------------------------------------------
21 7,662,006,442 (100.0%) PROGRAM TOTALS
22
23 --------------------------------------------------------------------------------
24 Ir file:function
25 --------------------------------------------------------------------------------
26 1,335,146,312 (17.43%) ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_unaligned_erms [/usr/lib/x86_64-linux-gnu/libc.so.6]
27 1,255,927,115 (16.39%) ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:__memcpy_avx_unaligned_erms [/usr/lib/x86_64-linux-gnu/libc.so.6]
28 767,318,807 (10.01%) ./malloc/./malloc/malloc.c:_int_free [/usr/lib/x86_64-linux-gnu/libc.so.6]
29 748,924,400 ( 9.77%) ./malloc/./malloc/malloc.c:_int_malloc [/usr/lib/x86_64-linux-gnu/libc.so.6]
30 424,929,976 ( 5.55%) ./malloc/./malloc/malloc.c:malloc [/usr/lib/x86_64-linux-gnu/libc.so.6]
31 191,346,740 ( 2.50%) ./malloc/./malloc/malloc.c:free [/usr/lib/x86_64-linux-gnu/libc.so.6]
32 152,418,873 ( 1.99%) ./malloc/./malloc/malloc.c:malloc_consolidate [/usr/lib/x86_64-linux-gnu/libc.so.6]
33 107,482,497 ( 1.40%) ./string/../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:__memcmp_avx2_movbe [/usr/lib/x86_64-linux-gnu/libc.so.6]
34 105,946,368 ( 1.38%) ???:operator new(unsigned long) [/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30]
35 96,170,106 ( 1.26%) ???:hobot::pack_sdk::Meta::GetDataIndex(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int) const [/home/lzy/work/acvi te_code/master/mfc5j3_appsw_libconvert/build/ubuntu/output/bin/comm_plugin_manager]
36 94,600,118 ( 1.23%) ./malloc/./malloc/arena.c:free
37 82,278,706 ( 1.07%) ???:std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(char const*) const [/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30] 38 60,595,452 ( 0.79%) ???:ObstacleProto::WorldSpaceInfo::MergeFrom(ObstacleProto::WorldSpaceInfo const&) [/home/lzy/work/acvite_code/master/mfc5j3_appsw_libconvert/build/ubuntu/outp ut/lib/libspi-protocol-convert.so]
39 58,554,462 ( 0.76%) ./malloc/./malloc/malloc.c:unlink_chunk.constprop.0 [/usr/lib/x86_64-linux-gnu/libc.so.6]
40 54,806,504 ( 0.72%) ???:hobot::pack_sdk::Meta::GetTopicMeta(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, std::vector<long, std::all ocator<long> >*, std::vector<long, std::allocator<long> >*, std::vector<void const*, std::allocator<void const*> >*, std::vector<unsigned long, std::allocator<unsigned long> >*) const [/home/lzy/work/acvite_code/master/mfc5j3_appsw_libconvert/build/ubuntu/output/bin/comm_plugin_manager]
41 52,638,193 ( 0.69%) ???:ObstacleProto::Obstacle::MergeFrom(ObstacleProto::Obstacle const&) [/home/lzy/work/acvite_code/master/mfc5j3_appsw_libconvert/build/ubuntu/output/lib/libsp i-protocol-convert.so]
42 52,069,931 ( 0.68%) ???:std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::al locator<char> > const&) [/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30]
43 47,538,816 ( 0.62%) ???:PerceptionBaseProto::Point::MergeFrom(PerceptionBaseProto::Point const&) [/home/lzy/work/acvite_code/master/mfc5j3_appsw_libconvert/build/ubuntu/output/lib /libspi-protocol-convert.so]
44 46,026,687 ( 0.60%) ./string/../sysdeps/x86_64/multiarch/strlen-avx2.S:__strlen_avx2 [/usr/lib/x86_64-linux-gnu/libc.so.6]
Análisis Fragmento Uno
En este informe, los porcentajes entre paréntesis representan el porcentaje de eventos "Ir" (lectura de instrucción). Esta es una medida de cuántas veces se recuperaron las instrucciones en esta función (y posiblemente se ejecutaron) como un porcentaje del número total de instrucciones obtenidas durante la ejecución del programa.
En este contexto, "Ir" significa "Instrucción leída", que es el número de instrucciones leídas. Este número indica cuántas instrucciones fueron obtenidas por el procesador durante la ejecución del programa.
La línea "7.662.006.442 (100,0%) TOTALES DEL PROGRAMA" indica que se leyeron un total de 7.662.006.442 instrucciones durante toda la ejecución del programa.
Por ejemplo, para la siguiente línea:
1,335,146,312 (17.43%) ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_unaligned_erms [/usr/lib/x86_64-linux-gnu/libc.so.6]
Esto significa que __memset_avx2_unaligned_erms
las instrucciones de la función se recuperaron 1 335 146 312 veces, lo que representa el 17,43 % del total de instrucciones recuperadas.
Esta métrica puede ayudarlo a comprender dónde se encuentran los cuellos de botella en el rendimiento de su programa. Si una función tiene un alto porcentaje de búsquedas de instrucciones, probablemente signifique que esta función es un punto de acceso en su programa, y es posible que deba optimizar esta función para mejorar el rendimiento de su programa.
Tenga en cuenta que esta métrica no indica directamente cuántas veces se llamó a una función o cuánto tiempo tomó. El número de búsquedas de instrucciones para una función puede variar debido a factores como su tamaño, el número de veces que se llama, la complejidad de su código, etc. Si desea saber cuántas veces se llama a una función o cuánto tarda, es posible que deba utilizar otras herramientas o técnicas de generación de perfiles.
Ejemplo de fragmento de informe de análisis de rendimiento 2
. void IdAdaptor::UpdateMap(
. std::map<uint32_t, uint8_t> ¤t_map_,
. std::map<uint32_t, uint8_t> &history_map_,
. const std::vector<ObstacleProto::Obstacle> &object,
. uint16_t trackAge[],
40,766 ( 0.00%) uint8_t trackAgeSize) {
. // clear the current_map_
. current_map_.clear();
2,398 ( 0.00%) int objects_size = object.size();
. std::vector<uint32_t> new_id;
. std::vector<uint8_t> vec_current_id;
19,184 ( 0.00%) if ((trackAge == nullptr)|| (objects_size <= 0) || (trackAgeSize <= 0)) {
. return;
. }
Análisis Fragmento Dos
En el informe, los porcentajes entre paréntesis siguen representando el porcentaje de eventos "Ir" (lectura de instrucciones). Esta es una medida de cuántas veces se recuperaron las instrucciones en esta función (y posiblemente se ejecutaron) como un porcentaje del número total de instrucciones obtenidas durante la ejecución del programa.
Para su función IdAdaptor::UpdateMap
, las búsquedas de instrucciones como porcentaje del total de búsquedas de instrucciones es 0.00%. Esto significa que durante la ejecución de su programa, la cantidad de veces que se leen las instrucciones en esta función es muy pequeña en comparación con la cantidad de instrucciones leídas en todo el programa.
Esto podría deberse a que la función se llama con menos frecuencia, el código de esta función es más corto o la ejecución de esta función está optimizada. En cualquier caso, esto significa que esta función probablemente no sea el cuello de botella de rendimiento de su programa.
Tenga en cuenta que esta métrica no indica directamente cuántas veces se llamó a una función o cuánto tiempo tomó. El número de búsquedas de instrucciones para una función puede variar debido a factores como su tamaño, el número de veces que se llama, la complejidad de su código, etc. Si desea saber cuántas veces se llama a una función o cuánto tarda, es posible que deba utilizar otras herramientas o técnicas de generación de perfiles.
Comparación con otras herramientas
perf
yValgrind
perf
Callgrind y Valgrind son herramientas de análisis de rendimiento, pero tienen algunas diferencias importantes en diseño y uso.
- Modo de recopilación de datos :
perf
es un analizador de muestreo basado en eventos que verifica periódicamente el estado del sistema (por ejemplo, cada cierto número de ciclos de CPU) y registra las funciones que se están ejecutando actualmente. Este enfoque puede proporcionar información sobre qué funciones pasan la mayor parte del tiempo en la CPU, pero puede perder algunas llamadas de función breves pero frecuentes. Callgrind, por otro lado, es un generador de perfiles basado en simulación que registra todas las llamadas a funciones y lecturas de instrucciones de un programa, lo que puede proporcionar información más detallada, pero también puede resultar en una mayor sobrecarga de rendimiento. - Información disponible :
perf
se pueden recopilar varios tipos de eventos de rendimiento, incluidos ciclos de CPU, aciertos/errores de caché, predicciones erróneas de sucursales y más. Esto puede ayudarlo a comprender cómo se comporta su programa a nivel de hardware. Callgrind, por otro lado, se enfoca en el comportamiento del programa, como llamadas a funciones y búsquedas de instrucciones. También puede proporcionar información sobre el uso de la memoria y el flujo de datos. - Facilidad de uso y portabilidad :
perf
parte de Linux, está disponible en todos los sistemas Linux, pero es posible que no esté disponible en otros sistemas operativos. Valgrind, por otro lado, es una herramienta independiente que se ejecuta en una variedad de sistemas operativos, incluidos Linux, macOS y Windows (a través de Cygwin o WSL).
En general, perf
Callgrind y Callgrind son herramientas poderosas que pueden proporcionar diferentes tipos de información de perfiles. La herramienta a elegir depende de sus necesidades específicas. En algunos casos, es posible que el uso conjunto de ambas herramientas proporcione el análisis de rendimiento más completo.
gperf
yValgrind
gprof
Valgrind y Valgrind son dos herramientas de análisis de rendimiento diferentes con algunas diferencias importantes en su diseño y uso.
- Modo de recopilación de datos :
gprof
es un perfilador basado en muestreo que funciona interrumpiendo periódicamente la ejecución del programa y registrando la función que se está ejecutando actualmente. Este enfoque puede proporcionar información sobre qué funciones pasan la mayor parte del tiempo en la CPU, pero puede perder algunas llamadas de función breves pero frecuentes. Por otro lado, la herramienta Callgrind de Valgrind es un generador de perfiles basado en simulación que registra todas las llamadas a funciones y lecturas de instrucciones de un programa, lo que puede proporcionar información más detallada, pero también puede resultar en una mayor sobrecarga de rendimiento. - Información disponible :
gprof
proporciona información sobre la cantidad de llamadas a funciones y el tiempo de ejecución acumulado de cada función, lo que puede ayudarlo a comprender qué funciones ocupan más tiempo en la ejecución del programa. Callgrind, por otro lado, proporciona información más detallada, incluida la cantidad de búsquedas de instrucciones, aciertos/errores de caché, predicciones erróneas de bifurcación, etc. para cada función. Esto puede ayudarlo a obtener una comprensión más profunda del comportamiento de su programa y los cuellos de botella en el rendimiento. - Facilidad de uso y portabilidad :
gprof
es parte de GNU binutils, que está disponible en todos los sistemas que soportan la cadena de herramientas GNU. Sin embargo, para usarlogprof
, necesita compilar su programa con-pg
la opción, lo que puede hacer que su programa se ejecute más lento. Valgrind, por otro lado, es una herramienta independiente que se ejecuta en una variedad de sistemas operativos, incluidos Linux, macOS y Windows (a través de Cygwin o WSL). El uso de Valgrind no requiere modificar las opciones de compilación, pero su sobrecarga de rendimiento suele sergprof
mayor que la de .
En general, gprof
Valgrind y Valgrind son herramientas poderosas que pueden proporcionar diferentes tipos de información de perfiles. La herramienta a elegir depende de sus necesidades específicas. En algunos casos, es posible que el uso conjunto de ambas herramientas proporcione el análisis de rendimiento más completo.
Cuadro comparativo
herramienta | Método de recopilación de datos | información disponible | Facilidad de uso y portabilidad | plataforma | Opciones de compilación requeridas |
---|---|---|---|---|---|
Puerta electoral | Perfilador basado en simulacros que registra todas las llamadas a funciones y lecturas de instrucciones | Proporciona información detallada, incluido el número de búsquedas de instrucciones, aciertos/errores de caché, predicciones erróneas de bifurcación y más para cada función. | Se ejecuta en varios sistemas operativos, incluidos Linux, macOS y Windows (a través de Cygwin o WSL) | Linux, mac OS, Windows (Cygwin, WSL) | ninguno |
gprof | Perfilador basado en muestreo al interrumpir periódicamente la ejecución del programa y registrar la función que se está ejecutando actualmente | Proporciona información sobre el número de llamadas a funciones y el tiempo de ejecución acumulado de cada función. | Es parte de GNU binutils y necesita ser compilado con -pg opciones |
Todos los sistemas que soportan la cadena de herramientas GNU | -pg |
rendimiento | Un analizador de muestreo basado en eventos que verifica periódicamente el estado del sistema y registra las funciones que se están ejecutando actualmente | Se pueden recopilar varios tipos de eventos de rendimiento, incluidos ciclos de CPU, aciertos/fallos de caché, predicciones erróneas de sucursales, etc. | es parte de Linux y solo está disponible en sistemas Linux | linux | ninguno |
Intel VTune | Un analizador de muestreo basado en eventos que verifica periódicamente el estado del sistema y registra las funciones que se están ejecutando actualmente | Proporciona información detallada sobre el análisis del rendimiento, incluido el tiempo de ejecución de la función, la tasa de aciertos de la memoria caché de la CPU, la precisión de la predicción de bifurcaciones, etc. | es un producto comercial de Intel y solo está disponible en sistemas compatibles con CPU Intel | Windows, Linux, mac OS | ninguno |
Generador de perfiles de Visual Studio | Un analizador de muestreo basado en eventos que verifica periódicamente el estado del sistema y registra las funciones que se están ejecutando actualmente | Proporciona información detallada de análisis de rendimiento, incluido el tiempo de ejecución de la función, el uso de la CPU, el uso de la memoria, etc. | es parte de Visual Studio y solo está disponible en sistemas Windows | ventanas | ninguno |
Instrumentos (macOS) | Un analizador de muestreo basado en eventos que verifica periódicamente el estado del sistema y registra las funciones que se están ejecutando actualmente | Proporciona información detallada de análisis de rendimiento, incluido el tiempo de ejecución de la función, el uso de la CPU, el uso de la memoria, etc. | es parte de Xcode y solo está disponible en sistemas macOS | Mac OS | ninguno |
Precauciones
Termina el proceso con gracia
No uses matar -9
kill -9
Matar un proceso de Valgrind en ejecución afectará los resultados de la detección. kill -9
matará el proceso inmediatamente sin darle la oportunidad de hacer ninguna limpieza. En el caso de Valgrind, esto significa que es posible que no pueda generar un informe completo, ya que generalmente genera informes cuando el programa instrumentado finaliza normalmente.
Si necesita detener Valgrind mientras se está ejecutando, lo mejor que puede hacer es intentar enviar una señal TERM con kill
el comando (sin -9
la opción). Esto le pedirá a Valgrind que finalice correctamente, debería poder generar un informe y luego salir.
kill <valgrind_pid>
Sin embargo, es posible que desee utilizar TERM si el proceso de Valgrind no responde a la señal TERM por algún motivo kill -9
. Tenga en cuenta que esto puede provocar que Valgrind no genere informes o que los informes generados estén incompletos.
En general, si es posible, debe evitar matar a Valgrind mientras se está ejecutando para asegurarse de que puede obtener informes completos y precisos. Si necesita detener Valgrind mientras se está ejecutando, debe intentar usar kill
el comando (sin -9
la opción) para terminarlo correctamente.
Las diferentes herramientas de Valgrind (como Memcheck, Callgrind, Massif, etc.) no pueden ejecutarse al mismo tiempo. Cada vez que ejecuta Valgrind, debe elegir una herramienta para usar. Esto se debe a que cada herramienta tiene sus propios objetivos y métodos específicos, y no se pueden aplicar a la misma instancia en ejecución del programa al mismo tiempo.
Ctrl+Z
No se puede cancelar el uso
Usar Ctrl+Z
en la línea de comando enviará una señal SIGSTOP al proceso actual en primer plano (Valgrind en este caso). Esto hace que el proceso suspenda la ejecución, pero no lo finaliza. Puede utilizar fg
el comando para reanudar un proceso suspendido.
En el caso de Valgrind, el uso Ctrl+Z
no afecta directamente sus resultados de detección, ya que solo suspende el proceso, no lo finaliza. Sin embargo, si modifica el estado del programa que está instrumentando mientras Valgrind está en pausa, o si realiza otras operaciones que podrían afectar los resultados de la instrumentación, esto puede afectar los informes de Valgrind.
En general, si solo desea detener temporalmente Valgrind y reanudarlo más tarde, Ctrl+Z
está bien usarlo. Sin embargo, debe evitar hacer cualquier cosa que pueda afectar los resultados de la detección mientras Valgrind está en pausa.
La señal TERM debe enviarse con los parámetros predeterminados de killall o kill
-
kill
comando para enviar una señal al ID de proceso especificado. Por ejemplo,kill 12345
la señal TERM se envía al proceso ID 12345. -
killall
comando para enviar una señal a todos los procesos cuyos nombres coincidan. Por ejemplo,killall myprogram
enviaría la señal TERM a todos los procesos denominados "myprogram".Si no se especifica ninguna señal,
kill
amboskillall
envían por defecto la señal TERM, que es una señal que solicita que el proceso finalice correctamente. Puede usar-s
opciones para especificar qué señal enviar, por ejemplo,kill -s HUP 12345
okillall -s HUP myprogram
.
Las herramientas no se pueden usar al mismo tiempo.
Las diferentes herramientas de Valgrind (como Memcheck, Callgrind, Massif, etc.) no pueden ejecutarse al mismo tiempo. Cada vez que ejecuta Valgrind, debe elegir una herramienta para usar. Esto se debe a que cada herramienta tiene sus propios objetivos y métodos específicos, y no se pueden aplicar a la misma instancia en ejecución del programa al mismo tiempo.
Por ejemplo, si desea realizar una detección de fugas de memoria, debe usar la herramienta Memcheck:
valgrind --tool=memcheck --leak-check=yes your_program [your_program_arguments]
Si desea realizar perfiles, debe usar la herramienta Callgrind:
valgrind --tool=callgrind your_program [your_program_arguments]
Si desea realizar la detección de fugas de memoria y la creación de perfiles al mismo tiempo, debe ejecutar Valgrind dos veces, una con Memcheck y otra con Callgrind.
Tenga en cuenta que, si bien esto puede llevar más tiempo, esto garantiza que los resultados que obtenga sean precisos y confiables. Si intenta ejecutar ambas herramientas al mismo tiempo, puede generar resultados confusos e inexactos.
epílogo
La comprensión es un paso importante hacia el siguiente nivel en nuestro viaje de aprendizaje de programación. Sin embargo, dominar nuevas habilidades e ideas siempre requiere tiempo y persistencia. Desde un punto de vista psicológico, el aprendizaje suele ir acompañado de pruebas y errores y ajustes continuos, que es como si nuestro cerebro optimizara gradualmente su "algoritmo" para resolver problemas.
Por eso, cuando nos encontramos con errores, debemos verlos como oportunidades para aprender y mejorar, no solo como obsesiones. Al comprender y resolver estos problemas, no solo podemos corregir el código actual, sino también mejorar nuestra capacidad de programación y evitar que se cometan los mismos errores en proyectos futuros.
Animo a todos a participar activamente y mejorar continuamente sus habilidades de programación. Ya sea que sea un principiante o un desarrollador experimentado, espero que mi blog pueda ayudarlo en su viaje de aprendizaje. Si encuentra útil este artículo, puede hacer clic para marcarlo o dejar sus comentarios para compartir sus ideas y experiencias. También puede hacer sugerencias y preguntas sobre el contenido de mi blog. Cada me gusta, comentario, compartir y seguir es el mayor apoyo para mí y la motivación para seguir compartiendo y creando.
Lea mi página de inicio de CSDN para desbloquear contenido más emocionante: la página de inicio de Bubble CSDN