lal*_*rde 5 gcc profiling debug-symbols
我已经编译了一个项目(openssh,但这并不重要)
CFLAGS="-ggdb3 -O0 -lm -finstrument-functions"
Run Code Online (Sandbox Code Playgroud)
符号表是(小提取):
nm -o somepath/sbin/sshd
/mypath/install/sbin/sshd:000f3548 d auth_method
/mypath/install/sbin/sshd:0001a90f t auth_openfile
/mypath/install/sbin/sshd:0001ab90 T auth_openkeyfile
/mypath/install/sbin/sshd:0001ac31 T auth_openprincipals
/mypath/install/sbin/sshd:0001d73a T auth_parse_options
/mypath/install/sbin/sshd:0000e362 T auth_password
Run Code Online (Sandbox Code Playgroud)
我打印函数地址时获得的__cyg_profile_func_enter|exit是:
0xb768f8ee
0xb768f66c
0xb768f66c
0xb76d9ae8
Run Code Online (Sandbox Code Playgroud)
显然是不一样的范围,在看了所有的数字后确认.
据我所知,nm提供偏移地址.什么__cyg_profile_func_enter时候项目中有很多文件?是否还有其他转换功能?
从gcc文档中,不应该:
void __cyg_profile_func_enter (void *this_fn,
void *call_site);
void __cyg_profile_func_exit (void *this_fn,
void *call_site);
The first argument is the address of the start of the current function, which may be looked up exactly in the symbol table.
Run Code Online (Sandbox Code Playgroud)
那么,我想让它做什么工作呢?
编辑:我的ptrace.c,我添加了一个互斥锁
#if (__GNUC__>2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ > 95))
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/errno.h>
#include <pthread.h>
#define PTRACE_PIPENAME "TRACE"
#define REFERENCE_OFFSET "REFERENCE:"
#define FUNCTION_ENTRY "enter"
#define FUNCTION_EXIT "exit"
#define END_TRACE "EXIT"
#define __NON_INSTRUMENT_FUNCTION__ __attribute__((__no_instrument_function__))
#define PTRACE_OFF __NON_INSTRUMENT_FUNCTION__
#define STR(_x) #_x
#define DEF(_x) _x
#define GET(_x,_y) _x(_y)
#define TRACE __GNU_PTRACE_FILE__
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
/** Initial trace open */
static FILE *__GNU_PTRACE_FILE__;
/** Final trace close */
static void
__NON_INSTRUMENT_FUNCTION__
gnu_ptrace_close(void)
{
fprintf(TRACE, END_TRACE " %ld\n", (long)getpid());
int res = fflush(TRACE);
if (res < 0) {
printf("Erreur sur gnu_ptrace_close / fflush\n");
}
if (TRACE != NULL)
fclose(TRACE);
pthread_mutex_destroy(&lock);
return ;
}
/** Trace initialization */
static int
__NON_INSTRUMENT_FUNCTION__
gnu_ptrace_init(void)
{
struct stat sta;
__GNU_PTRACE_FILE__ = NULL;
/* See if a trace file exists */
if (stat(PTRACE_PIPENAME, &sta) != 0)
{
/* No trace file: do not trace at all */
return 0;
}
else
{
/* trace file: open up trace file */
if ((TRACE = fopen(PTRACE_PIPENAME, "a")) == NULL)
{
char *msg = strerror(errno);
perror(msg);
printf("[gnu_ptrace error]\n");
return 0;
}
#ifdef PTRACE_REFERENCE_FUNCTION
fprintf(TRACE,"%s %s %p\n",
REFERENCE_OFFSET,
GET(STR,PTRACE_REFERENCE_FUNCTION),
(void *)GET(DEF,PTRACE_REFERENCE_FUNCTION));
#endif
/* Tracing requested: a trace file was found */
atexit(gnu_ptrace_close);
return 1;
}
}
/** Function called by every function event */
void
__NON_INSTRUMENT_FUNCTION__
gnu_ptrace(char * what, void * p)
{
static int first=1;
static int active=1;
int res = 0;
if (active == 0)
return;
if (first)
{
active = gnu_ptrace_init();
first = 0;
if (active == 0)
return;
}
if (!what || !p) {
printf("Erreur, what ou p NULL\n");
return;
}
if (strcmp(what, FUNCTION_ENTRY) && strcmp(what, FUNCTION_EXIT)) {
printf("Erreur, what incorrect\n");
return;
}
printf("----------------------- what=%s p=%p\n", what, p);
res = fprintf(TRACE, "%s %p\n", what, p);
if (res < 0) {
printf("Erreur sur gnu_ptrace / fprintf\n");
/* active = 0;*/
}
if (res > 0) res = fflush(TRACE);
if (res < 0) {
printf("Erreur sur gnu_ptrace / fflush\n");
active = 0;
}
return;
}
/** According to gcc documentation: called upon function entry */
void
__NON_INSTRUMENT_FUNCTION__
__cyg_profile_func_enter(void *this_fn, void *call_site)
{
pthread_mutex_lock(&lock);
gnu_ptrace(FUNCTION_ENTRY, this_fn);
(void)call_site;
pthread_mutex_unlock(&lock);
}
/** According to gcc documentation: called upon function exit */
void
__NON_INSTRUMENT_FUNCTION__
__cyg_profile_func_exit(void *this_fn, void *call_site)
{
pthread_mutex_lock(&lock);
gnu_ptrace(FUNCTION_EXIT, this_fn);
(void)call_site;
pthread_mutex_unlock(&lock);
}
#endif
Run Code Online (Sandbox Code Playgroud)
这是带有JHiant想法的修改过的ptrace.c.我已经与-ldl链接了
#include <dlfcn.h>
Run Code Online (Sandbox Code Playgroud)
_
Dl_info finfo;
if (!dladdr(p, &finfo))
printf("Erreur, dladdr\n");
/* res = fprintf(TRACE, "%s %p\n", what, p); */
res = fprintf(TRACE, "%s %p %s (%s)\t\n", what, p, finfo.dli_sname, finfo.dli_fname);
Run Code Online (Sandbox Code Playgroud)
这是获得的痕迹(第一行):
enter 0xb7494974 OPENSSL_cpuid_setup (/home/laurent/Documents/projet/install/lib/libcrypto.so.1.0.0)
exit 0xb7494974 OPENSSL_cpuid_setup (/home/laurent/Documents/projet/install/lib/libcrypto.so.1.0.0)
enter 0xb76ac470 main (/home/laurent/Documents/projet/install/sbin/sshd)
enter 0xb76b34fe (null) (/home/laurent/Documents/projet/install/sbin/sshd)
exit 0xb76b34fe (null) (/home/laurent/Documents/projet/install/sbin/sshd)
enter 0xb7749384 (null) (/home/laurent/Documents/projet/install/sbin/sshd)
enter 0xb770496e (null) (/home/laurent/Documents/projet/install/sbin/sshd)
enter 0xb77046ec (null) (/home/laurent/Documents/projet/install/sbin/sshd)
exit 0xb77046ec (null) (/home/laurent/Documents/projet/install/sbin/sshd)
enter 0xb774eb68 (null) (/home/laurent/Documents/projet/install/sbin/sshd)
exit 0xb774eb68 (null) (/home/laurent/Documents/projet/install/sbin/sshd)
exit 0xb770496e (null) (/home/laurent/Documents/projet/install/sbin/sshd)
exit 0xb7749384 (null) (/home/laurent/Documents/projet/install/sbin/sshd)
Run Code Online (Sandbox Code Playgroud)
其他行显示null所有时间而不是函数名称.我检查了sshd映射,使用了带符号的右侧libcrypto构建.上面的描述中令人惊讶的是它只显示了一个对libcrypto的调用,它看起来就像名称所显示的一样.
编译OpenSSH(在控制台中提取一行make执行 - 所有都有相同的选项 - 通常没有-fpic,但结果跟踪是相同的):
gcc -ggdb3 -O0 -lm -finstrument-functions -ldl -fpic -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-all -fPIE -I. -I. -I/home/laurent/Documents/projet/install/include -DSSHDIR=\"/home/laurent/Documents/projet/install/etc\" -D_PATH_SSH_PROGRAM=\"/home/laurent/Documents/projet/install/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/home/laurent/Documents/projet/install/libexec/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/home/laurent/Documents/projet/install/libexec/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/home/laurent/Documents/projet/install/libexec/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/home/laurent/Documents/projet/install/libexec/ssh-pkcs11-helper\" -D_PATH_SSH_PIDDIR=\"/var/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c ssh-keyscan.c
Run Code Online (Sandbox Code Playgroud)
编译OpenSSL(在控制台中提取一行make执行 - 都具有相同的选项):
gcc -I.. -I../.. -I../modes -I../asn1 -I../evp -I../../include -ggdb3 -O0 -lm -finstrument-functions -ldl -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -DL_ENDIAN -DTERMIO -fomit-frame-pointer -Wall -DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DRMD160_ASM -DAES_ASM -DVPAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -c -o cms_lib.o cms_lib.c
Run Code Online (Sandbox Code Playgroud)
为什么OpenSSL/libcrypto没有更多的痕迹?
除了"main"之外,为什么跟踪中没有函数名?
几个想法:
#include <dlfcn.h>
__cyg_profile_func_enter(void *func, void *site)
{
DL_info finfo;
dladdr(fun, &finfo);
fprintf(log, "Entered &s", finfo.dli_sname);
}
Run Code Online (Sandbox Code Playgroud)