Невозможно профилировать методы libcrypto с помощью gprof

Я пытаюсь профилировать программу C, которая использует некоторые методы openssl/libcrypto. Все работает хорошо, когда я компилирую и запускаю код без информации о профилировании. Когда я добавляю параметры для его профилирования с помощью gprof, я получаю неожиданные результаты от инструмента профилирования.

Я провел много исследований, но не нашел ни одной страницы, которая решила бы мою проблему.

Это мой код (с именем test.c):

#include <stdio.h>
#include <openssl/bn.h>
#include <openssl/rand.h>

static BIGNUM *x;
static BIGNUM *y;
static BIGNUM *z;
static BIGNUM *p;
static BN_CTX *tmp;
static unsigned int max_size;

int main(void){

  int max_bytes, res_gen;
  max_bytes  = 50;

  tmp = BN_CTX_new();
  BN_CTX_init(tmp);
  x = BN_new();
  y = BN_new();
  z = BN_new();
  p = BN_new();

  RAND_load_file("/dev/urandom", max_bytes);

 max_size = 256; 
 BN_rand(x, max_size, 0, 0);
 BN_rand(y, max_size, 0, 0);
 res_gen = BN_generate_prime_ex(p, max_size, 0, NULL, NULL, NULL);

 BN_mul(z, x, y, tmp);
 BN_nnmod(x, z, p, tmp);

 printf("\nOk\n");

 BN_free(x);
 BN_free(y);
 BN_free(z);
 BN_free(p);
 BN_CTX_free(tmp); 

 return 0;
}

Когда я компилирую информацию о профилировании с помощью gcc -pg -static test.c -lcrypto -ldl, это дает следующие результаты. Я получаю 0% (и 0 секунд) за все, что неожиданно.

Flat profile:

Each sample counts as 0.01 seconds.
no time accumulated

%   cumulative   self              self     total           
time   seconds   seconds    calls  Ts/call  Ts/call  name    
0.00      0.00     0.00        1     0.00     0.00  main


                         Call graph

granularity: each sample hit covers 2 byte(s) no time propagated

index % time    self  children    called     name
                0.00    0.00       1/1           __libc_start_main [4282]
[1]      0.0    0.00    0.00       1         main [1]
                0.00    0.00       0/0           mcount (3495)
                0.00    0.00       0/0           BN_CTX_new [275]
                0.00    0.00       0/0           BN_CTX_init [274]
                0.00    0.00       0/0           BN_new [372]
                0.00    0.00       0/0           RAND_load_file [1636]
                0.00    0.00       0/0           BN_rand [386]
                0.00    0.00       0/0           BN_generate_prime_ex [331]
                0.00    0.00       0/0           BN_mul [370]
                0.00    0.00       0/0           BN_nnmod [378]
                0.00    0.00       0/0           puts [3696]
                0.00    0.00       0/0           BN_free [327]
                0.00    0.00       0/0           BN_CTX_free [272]
-----------------------------------------------

Кроме того, кажется, что профилировщик обнаруживает только основной метод, потому что сведения о других методах не отображаются в плоском профиле и графе вызовов.

Итак, я хотел бы знать, должен ли я скомпилировать библиотеку OpenSSL с некоторыми параметрами (какими параметрами?) Или что-то еще.


person Yssouf    schedule 05.04.2016    source источник
comment
@jww: Спасибо за модификации. Я не знал, как добавить это изображение напрямую. Первая ошибка команды - это то, что приводит меня ко второй. Кроме того, я добавил второе изображение для результатов второй команды.   -  person Yssouf    schedule 06.04.2016
comment
@jww: текст добавлен (надеюсь, правильно)   -  person Yssouf    schedule 06.04.2016
comment
Да, выглядит нормально, спасибо. И он также хорошо протестирован: поиск Google BN_CTX_new gprof. Ваш вопрос находится в топе результатов, что означает, что он проиндексирован для будущих посетителей.   -  person jww    schedule 06.04.2016
comment
Что-то еще, что вы можете сделать, если хотите узнать, сколько раз вызывается функция, это использовать опцию -coverage. Он не показывает процессорное время, но показывает количество вызовов каждой функции. Я использую его для других проектов, чтобы убедиться, что в коде есть тестовые примеры, которые реализуют определенный путь кода. Это может показать вам отвлекающий маневр в вашем коде. Например, BN_new и BN_exp имеют разные временные затраты (распределение менее затратно, чем возведение в степень), поэтому вам нужно заранее иметь представление (которое, похоже, вы и пытаетесь обнаружить).   -  person jww    schedule 06.04.2016


Ответы (1)


gprof — это CPU-профилировщик. Это означает, что он не может учитывать время, потраченное на блокировку системных вызовов, таких как ввод-вывод, сон, блокировки и т. д.

Предполагая, что цель состоит в том, чтобы найти ускорение, многие люди запускают его под отладчиком, таким как GDB, и берут образцы стека. вручную.

Это не измерение (с какой-либо точностью). Это выявление проблем. Все, что вы видите, что он делает, чего вы могли бы избежать, если вы видите это более чем на одном образце, даст вам существенное ускорение. Чем меньше семплов вам нужно сделать, прежде чем вы увидите это дважды, тем больше будет ускорение.

person Mike Dunlavey    schedule 05.04.2016