0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CentOS 7 へ 関数コールトレーサ tracef (hogetrace) をインストール

Last updated at Posted at 2018-10-15

概要

tracef は関数コールトレーサです。システムコールトレーサのstraceやptraceと類似の機能を持ち、独自関数もトレースしてくれるものです。もともとhogetraceという名で開発されたようですが、tracefに改称されています。
開発者のページは ここ (http://binary.nahi.to/hogetrace/) にあるのですが文字化けがひどい、かつ、詰まった部分があるのでインストール手順を記載します。なお、開発者ページ原本はUTF-8でエンコーディングすれば読めます。

インストール

開発者のページにあるインストール手順に沿ってインストールします。

1. 必要なパッケージをインストール

  • gcc-c++
  • libstdc++-devel
  • binutils-devel
  • elfutils-libelf-devel
  • boost-devel
  • libdwarf

2. ひとまず configure そして make

$ tar xvzf tracef-0.1.tar.gz
$ cd tracef-0.1
$ ./configure
$ cd src
$ make

3. エラー発生!!

上記手順のmakeで以下のようなエラーが発生します。

$ make
if g++ -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -MT prototype.o -MD -MP -MF ".deps/prototype.Tpo" -c -o prototype.o `test -f 'ftrace/prototype.cpp' || echo './'`ftrace/prototype.cpp; \
then mv -f ".deps/prototype.Tpo" ".deps/prototype.Po"; else rm -f ".deps/prototype.Tpo"; exit 1; fi
In file included from ./main.h:20:0,
                 from ftrace/prototype.cpp:12:
./main.h:23:28: error: ‘uintptr_t’ was not declared in this scope
 BOOST_STATIC_ASSERT(sizeof(uintptr_t) == sizeof(unsigned long));
                            ^
./main.h:23:1: error: template argument 1 is invalid
 BOOST_STATIC_ASSERT(sizeof(uintptr_t) == sizeof(unsigned long));
 ^
ftrace/prototype.cpp:38:35: error: ‘elf’ is not a type
   int prototype_add_elf(Elf *elf, elf& pelf);
                                   ^
ftrace/prototype.cpp:52:35: error: ‘elf’ is not a type
   int prototype_add_elf(Elf *elf, elf& pelf)
                                   ^
ftrace/prototype.cpp: In function ‘int {anonymous}::prototype_add_elf(Elf*, int&)’:
ftrace/prototype.cpp:79:38: error: invalid initialization of reference of type ‘hoge::elf&’ from expression of type ‘int’
       prototype_add_cu(dbg, die, pelf);
                                      ^
ftrace/prototype.cpp:39:7: error: in passing argument 3 of ‘int {anonymous}::prototype_add_cu(Dwarf_Debug, Dwarf_Die, hoge::elf&)’
   int prototype_add_cu(Dwarf_Debug dbg, Dwarf_Die die, 
       ^
ftrace/prototype.cpp: In function ‘int hoge::get_debug_info(pid_t, hoge::elf&)’:
ftrace/prototype.cpp:379:30: error: invalid initialization of reference of type ‘int&’ from expression of type ‘hoge::elf’
     prototype_add_elf(e, pelf);
                              ^
ftrace/prototype.cpp:52:7: error: in passing argument 2 of ‘int {anonymous}::prototype_add_elf(Elf*, int&)’
   int prototype_add_elf(Elf *elf, elf& pelf)
       ^
make: *** [prototype.o] Error 1

4. エラー解決

  • まず、uintptr_tに関する解決法ですが、関連するファイルに #include <stdint.h>を追記すればOKです。
  • 次に、elfに関するタイプエラーですが、ftrace/prototype.cppの38,53行目でelf&hoge::elf&に変更します。

5. 次なるエラー発生

$ make
if g++ -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -MT printer.o -MD -MP -MF ".deps/printer.Tpo" -c -o printer.o printer.cpp; \
then mv -f ".deps/printer.Tpo" ".deps/printer.Po"; else rm -f ".deps/printer.Tpo"; exit 1; fi
printer.cpp:17:22: fatal error: asm/user.h: No such file or directory
 #include <asm/user.h>
                      ^
compilation terminated.
make: *** [printer.o] Error 1

6. 再びエラー解決

printer.cppの17行目#include <asm/user.h>を、#include <sys/user.h>へ変更します。

なお、次にmakeすると同じエラーが他のファイルでも出るので、 #include <sys/user.h>へ変更します。

7. またまたエラー発生

$ make
if g++ -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -MT trace.o -MD -MP -MF ".deps/trace.Tpo" -c -o trace.o trace.cpp; \
then mv -f ".deps/trace.Tpo" ".deps/trace.Po"; else rm -f ".deps/trace.Tpo"; exit 1; fi
trace.cpp: In member function ‘uintptr_t hoge::tracer::get_word(uintptr_t) const’:
trace.cpp:95:51: error: ‘CHAR_BIT’ was not declared in this scope
         ret |= (static_cast<uintptr_t>(b) << (i * CHAR_BIT));  
                                                   ^
trace.cpp: In member function ‘void hoge::tracer::set_word(uintptr_t, uintptr_t)’:
trace.cpp:119:40: error: ‘CHAR_BIT’ was not declared in this scope
         sinsn_t b = (w & mask) >> (i * CHAR_BIT);
                                        ^
make: *** [trace.o] Error 1

8. 再び再びエラー解決 && インストール完了

printer.cpp#include <climits>を追記し、インストール完了です。

テスト

~/test/test.c
#include <stdio.h>

void myfunc2(){
  printf("hello world");
}

void myfunc1(){
  myfunc2();
}

int main(int argc, char** argv){
  myfunc1();
  myfunc2();
  return 0;
}
$ gcc -o ~/test/test.o ~/test/test.c
$ ./tracef --synthetic -flATu ~/test/test.o
[pid 31896] 16:58:31.883982 +++ process 31896 attached (ppid 31895) +++
[pid 31896] 16:58:31.884654 === symbols loaded: '/home/pepper/test/test.o' ===
[pid 31896] 16:58:31.884957 ==> _start() at 0x0000000000400430
[pid 31896] 16:58:31.885269    ==> __libc_start_main@plt() at 0x0000000000400410
[pid 31896] 16:58:31.885524       ==> __libc_csu_init() at 0x0000000000400570
[pid 31896] 16:58:31.885725          ==> _init() at 0x00000000004003c8
[pid 31896] 16:58:31.885866          <== _init() [rax = 0x0]
[pid 31896] 16:58:31.885959          ==> frame_dummy() at 0x00000000004004f0
[pid 31896] 16:58:31.886098          ==> register_tm_clones() at 0x0000000000400490
[pid 31896] 16:58:31.886235          <== register_tm_clones() [rax = 0x0]
[pid 31896] 16:58:31.886322       <== __libc_csu_init() [rax = 0x0]
[pid 31896] 16:58:31.886404       ==> main() at 0x0000000000400542
[pid 31896] 16:58:31.886491          ==> myfunc1() at 0x0000000000400532
[pid 31896] 16:58:31.886587             ==> myfunc2() at 0x000000000040051d
[pid 31896] 16:58:31.886714                ==> printf@plt() at 0x0000000000400400
[pid 31896] 16:58:31.886851                <== printf@plt() [rax = 0xb]
[pid 31896] 16:58:31.887001             <== myfunc2() [rax = 0xb]
[pid 31896] 16:58:31.887135          <== myfunc1() [rax = 0xb]
[pid 31896] 16:58:31.887257          ==> myfunc2() at 0x000000000040051d
[pid 31896] 16:58:31.887393             ==> printf@plt() at 0x0000000000400400
[pid 31896] 16:58:31.887539             <== printf@plt() [rax = 0xb]
[pid 31896] 16:58:31.887631          <== myfunc2() [rax = 0xb]
[pid 31896] 16:58:31.887715       <== main() [rax = 0x0]
[pid 31896] 16:58:31.887794       ==> __do_global_dtors_aux() at 0x00000000004004d0
[pid 31896] 16:58:31.887884       ==> deregister_tm_clones() at 0x0000000000400460
[pid 31896] 16:58:31.887982       <== deregister_tm_clones() [rax = 0x7]
[pid 31896] 16:58:31.888065       ==> _fini() at 0x00000000004005e4
[pid 31896] 16:58:31.888155       <== _fini() [rax = 0x4005e4]
hello worldhello world[pid 31896] 16:58:31.888314 +++ process 31896 detached (ppid 31895) +++
tracef: done
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?