C++ コンパイラオプションメモ

公開日:2018-11-24
最終更新:2018-11-24

いわゆるプログラミングコンテストというものにたまに出ている者だが、実行速度の制約上、未だにこの世界ではC++が主流であり、C++の周辺技術を抑えておくことにより、効率的なデバッグ、コーディングができると私は考えている。

普段からDEBUGマクロ仕込むとかでやってきたが、なんかTL見ていたらいろいろ情報があって、この記事に至ったが、なんか別の方法があるよとツイッターで言われたので調べた。

環境

  • OS: MacOS 10.14.1
  • GCC: g++-8 (Homebrew GCC 8.2.0) 8.2.0

結論

こんな感じのalias貼ることにした。

alias g++='g++-8 -Wall -std=c++14 -fsanitize=undefined '
alias gg++='g++-8 -g -DDEBUG -Wall -std=c++14 -fsanitize=undefined,address '

もともとデバッグ時に出したいときだけ -DDEBUG を書いて、マクロに入れるようにしていたが、 -fsanitize を追加した。

経緯

配列外参照の検出のため、 -D_GLIBCXX_DEBUG 入れるか、あるいはソースコード上に定義するかしようとした。

だが、 -fsanitize と一緒に使おうとしたところ、どうもコンパイル時に大量のログが出てきて気持ちが悪くなってしまったので、ログがたくさんでない方法を回避しようとする。

そこで、 -fsanitize=undefined,address として、上記のマクロを消すとうまくいくことがわかった。

ちなみにオーバーフロー時のログはこんな感じ。

test.cpp:72:17: runtime error: signed integer overflow: 10000000 * 10000000 cannot be represented in type 'int'
276447232

ちなみに配列外の参照の際はこんな感じに出る。

=================================================================
==28518==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040000003b8 at pc 0x000102fd95bf bp 0x7ffeecc26ea0 sp 0x7ffeecc26e98
WRITE of size 4 at 0x6040000003b8 thread T0
    #0 0x102fd95be in main test.cpp:7
    #1 0x7fff6a31c08c in start (libdyld.dylib:x86_64+0x1708c)

0x6040000003b8 is located 0 bytes to the right of 40-byte region [0x604000000390,0x6040000003b8)
allocated by thread T0 here:
    #0 0x1033673d0 in wrap__Znwm (libasan.5.dylib:x86_64+0x6e3d0)
    #1 0x102fda954 in __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) new_allocator.h:111
    #2 0x102fda75a in std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) alloc_traits.h:436
    #3 0x102fda67f in std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) stl_vector.h:296
    #4 0x102fda308 in std::_Vector_base<int, std::allocator<int> >::_M_create_storage(unsigned long) stl_vector.h:311
    #5 0x102fd9cb9 in std::_Vector_base<int, std::allocator<int> >::_Vector_base(unsigned long, std::allocator<int> const&) stl_vector.h:260
    #6 0x102fd9801 in std::vector<int, std::allocator<int> >::vector(unsigned long, std::allocator<int> const&) stl_vector.h:416
    #7 0x102fd9504 in main test.cpp:5
    #8 0x7fff6a31c08c in start (libdyld.dylib:x86_64+0x1708c)

SUMMARY: AddressSanitizer: heap-buffer-overflow test.cpp:7 in main
Shadow bytes around the buggy address:
  0x1c0800000020: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 05
  0x1c0800000030: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 05
  0x1c0800000040: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 07
  0x1c0800000050: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x1c0800000060: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 05
=>0x1c0800000070: fa fa 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa
  0x1c0800000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0800000090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c08000000a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c08000000b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c08000000c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==28518==ABORTING
zsh: abort      ./test

今度からのデバッグ速度向上に役立つといいなと思う。

参照

記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
技術ブログとは何なのだろう。なんかちょっと試してみたものをメモがてら残してみています。

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする