Posted at

osxでvalgrindが使えないときのtips

More than 1 year has passed since last update.


motivation


  • xcodeでプロジェクトを作らないのでinstrumentはそのまま使えない

  • valgrindを使っていたがhigh sierraで動かなくなっているらしいので代わりを探している


leaks command


  • instrumentの一部として入っているleaks command (/usr/bin/leaks) が使えそう。

  • ターゲットのバイナリを以下のようにして動かす

  MallocStackLogging=1 /path/to/debugging_binary


  • debugging_binaryの実行中にpidを調べて以下のコマンドを実行する。

  leaks $PID


  • 以下のようなフォーマットでメモリリークのアドレスとサイズ、メモリのコンテント、またmallocしたときのスタックトレースが見れる。

  Leak: 0x7fe950b8ea00  size=1536  zone: DefaultMallocZone_0x105c38000

0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
0x00000000 0x00000000 0x00000000 0x00000000 ................
...
Call stack: [thread 0x70000eb21000]: | thread_start | _pthread_body | _pthread_body | void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, net::NqWorker::Start(moodycamel::ConcurrentQueue<net::NqPacketReader::Packet*, moodycamel::ConcurrentQueueDefaultTraits>&)::'lambda'()> >(void*) type_traits:4291 | net::NqWorker::Start(moodycamel::ConcurrentQueue<net::NqPacketReader::Packet*, moodycamel::ConcurrentQueueDefaultTraits>&)::'lambda'()::operator()() const nq_worker.h:32 | net::NqWorker::Run(moodycamel::ConcurrentQueue<net::NqPacketReader::Packet*, moodycamel::ConcurrentQueueDefaultTraits>&) nq_worker.cpp:28 | net::NqLoop::Poll() nq_loop.cpp:101 | nq::Loop::Poll() loop.h:64 | non-virtual thunk to net::NqDispatcher::OnEvent(int, kevent const&) nq_dispatcher.cpp:0 | net::NqDispatcher::OnEvent(int, kevent const&) nq_dispatcher.cpp:46 | net::NqPacketReader::Read(int, int, net::QuicClock const&, net::NqPacketReader::Delegate*, unsigned long long*) nq_packet_reader.cpp:77 | net::NqPacketReader::ReadPackets(int, int, net::QuicClock const&, net::NqPacketReader::Delegate*, unsigned long long*) nq_packet_reader.cpp:165 | net::NqPacketReader::NewBuffer() nq_packet_reader.h:84 | operator new(unsigned long) | malloc | malloc_zone_malloc


  • 最初から一緒に実行するのではなく、必要な時に外部から実行できるのでvalgrindだと遅くなりすぎるようなときにも有用かもしれない