[Valgrind, una herramienta para la depuración de memoria integrada C/C++, detección de fugas de memoria y análisis de rendimiento] Una guía completa para el uso de herramientas Valgrind en Linux


inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

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:

  1. Abre una terminal.
  2. Primero, debe actualizar la lista de paquetes de su sistema. Se pueden utilizar los siguientes comandos:
    sudo apt-get update
    
  3. Luego, instala Valgrind con el siguiente comando:
    sudo apt-get install valgrind
    
  4. Una vez que se completa la instalación, puede verificar que Valgrind se instaló correctamente con el siguiente comando:
    valgrind --version
    
    Si Valgrind se instaló correctamente, se mostrará el número de versión de Valgrind.

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:

  1. 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
  2. Descomprima el paquete del código fuente e ingrese al directorio del código fuente:
    tar xvf valgrind-3.17.0.tar.bz2
    cd valgrind-3.17.0
    
    (Ajuste el número de versión en el comando anterior de acuerdo con la versión de Valgrind que descargó)
  3. 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
    
  4. Compilar Valgrind:
    make
    
  5. Finalmente, puede copiar el Valgrind compilado en su sistema de destino o usar make installel 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:

  1. 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=yesLa opción le dice a Valgrind que verifique si hay pérdidas de memoria.

  2. 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.pidarchivo llamado , donde pidestá el ID de proceso de su programa. Puede ms_printver el contenido de este archivo con el comando:

    ms_print massif.out.pid
    
  3. 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.pidarchivo llamado , donde pidestá el ID de proceso de su programa. Puede callgrind_annotatever 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 -gcompilados 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 -gla 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:2significa que la pérdida de memoria ocurre en la your_program.clí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 -O2o . -O3Si es posible, debe compilar su programa sin optimización para la detección de fugas de memoria.

Parámetros importantes


  • --leak-check=yesle 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=fullSe 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=allMuestra todos los tipos de fugas de memoria, incluidos "definitivamente perdido", "perdido indirectamente", "posiblemente perdido" y "todavía accesible".
  • --num-callers=nAumente la profundidad de la pila de llamadas.

--leak-check=fullObtendrá 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 funcde 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:

  1. Primero, inicie su programa, usando --vgdb=yesla opción para decirle a Valgrind que inicie gdbserver al inicio:
    valgrind --vgdb=yes --leak-check=full your_program [your_program_arguments]
    
  2. 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:
    gdb your_program
    (gdb) target remote | vgdb
    
    Esto iniciará gdb y se conectará a Valgrind.
  3. Ahora, puede usar el comando en gdb monitorpara interactuar con Valgrind. Por ejemplo, puede usar monitor leak_check full reachable anyel comando para verificar si hay pérdidas de memoria en tiempo de ejecución:
    (gdb) monitor leak_check full reachable any
    
    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.

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=allel 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.txtun archivo. Puede output.txtreemplazar con cualquier nombre de archivo que desee.

Además, Valgrind proporciona una --log-fileopció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.txtun 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.sodeterminadas 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.callocpthread_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.pidarchivo llamado , donde pidestá el ID de proceso de su programa. Puede ms_printver 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-fnopció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-fnopció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_allocacredite toda la memoria asignada por la función a my_allocla persona que llama al .

--pages-as-heapopció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, newetc.:

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 kcachegrindu 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 pidestá 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_printver y analizar este archivo de informe con el comando:

ms_print massif.out.pid

ms_printformateará 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_annotateo kcachegrindpara 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_annotateredirigir 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_annotatela salida en output.txtel archivo en lugar de mostrarla en la terminal. Si output.txtel 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_annotateagregará la salida de al output.txtfinal 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

kcachegrindy qcachegrindson 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:

  1. 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:
    valgrind --tool=callgrind your_program
    
    En este comando, your_programse encuentra el programa que desea analizar. Este comando produce un callgrind.out.pidarchivo llamado , donde pidestá el ID de proceso de su programa.
  2. Instale kcachegrind o qcachegrind : luego, debe instalar kcachegrindo qcachegrind. Puede instalar ambas herramientas a través de su administrador de paquetes. Por ejemplo, si está utilizando Ubuntu, puede instalarlo con el siguiente comando kcachegrind:
    sudo apt-get install kcachegrind
    
    Alternativamente, puede instalarlo con el siguiente comando qcachegrind:
    sudo apt-get install qcachegrind
    
  3. Activar la salida de Callgrind : finalmente, puede usar kcachegrindo qcachegrindpara activar la salida de Callgrind. Puede abrir el archivo con el siguiente comando callgrind.out.pid:
    kcachegrind callgrind.out.pid
    
    o:
    qcachegrind callgrind.out.pid
    
    En ambos comandos, callgrind.out.pides el archivo de salida de Callgrind.

kcachegrindy qcachegrindmostrará 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_annotateLa 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.

gprof2dotEs 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_ermslas 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> &current_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

perfyValgrind

perfCallgrind y Valgrind son herramientas de análisis de rendimiento, pero tienen algunas diferencias importantes en diseño y uso.

  1. Modo de recopilación de datos : perfes 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.
  2. Información disponible : perfse 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.
  3. Facilidad de uso y portabilidad : perfparte 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, perfCallgrind 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.

gperfyValgrind

gprofValgrind y Valgrind son dos herramientas de análisis de rendimiento diferentes con algunas diferencias importantes en su diseño y uso.

  1. Modo de recopilación de datos : gprofes 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.
  2. Información disponible : gprofproporciona 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.
  3. Facilidad de uso y portabilidad : gprofes parte de GNU binutils, que está disponible en todos los sistemas que soportan la cadena de herramientas GNU. Sin embargo, para usarlo gprof, necesita compilar su programa con -pgla 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 ser gprofmayor que la de .

En general, gprofValgrind 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 -pgopciones 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 -9Matar un proceso de Valgrind en ejecución afectará los resultados de la detección. kill -9matará 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 killel comando (sin -9la 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 killel comando (sin -9la 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+ZNo se puede cancelar el uso

Usar Ctrl+Zen 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 fgel comando para reanudar un proceso suspendido.

En el caso de Valgrind, el uso Ctrl+Zno 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+Zestá 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

  • killcomando para enviar una señal al ID de proceso especificado. Por ejemplo, kill 12345la señal TERM se envía al proceso ID 12345.

  • killallcomando para enviar una señal a todos los procesos cuyos nombres coincidan. Por ejemplo, killall myprogramenviaría la señal TERM a todos los procesos denominados "myprogram".

    Si no se especifica ninguna señal, killambos killallenvían por defecto la señal TERM, que es una señal que solicita que el proceso finalice correctamente. Puede usar -sopciones para especificar qué señal enviar, por ejemplo, kill -s HUP 12345o killall -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
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_21438461/article/details/131668820
Recomendado
Clasificación