惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
J
Java Code Geeks
博客园 - 聂微东
量子位
C
Check Point Blog
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
B
Blog
罗磊的独立博客
腾讯CDC
GbyAI
GbyAI
博客园 - 【当耐特】
A
About on SuperTechFans
M
MIT News - Artificial intelligence
U
Unit 42
D
Docker
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队

kefan.me

Two Classes 在冰岛抵抗白昼 用Rust重构了后端 写前端如逆水行舟 鱼王 Coding in Wenyan 去开会成为一个人新生活的标志 Install Clang-Format Without Root Privileges Build a Web App - Part 2/2 Build a Web App - Part 1/2 我说我不来你非要让我来 痛苦还是无聊 从零搭建博客 写前端不是请客吃饭 一些片段 Fetching Github Stats using GraphQL 适合私人沉迷 Odd Ways to Find Odd Numbers 关于李志 Miller-Rabin素性测试和大素数生成 你好,博客 再见
Running Valgrind on macOS Catalina
2020-02-16 · via kefan.me

Prologue

While I was doing my course on data structures and algorithms, I had a hard time trying to detect memory leaks in C++. Handling pointers are annoying especially when you have thousands lines of code and you’re not sure in which line a piece of memory is allocated but never freed before it goes out of scope.

Valgrind is a tool designed to detect memory leaks, unfortunately, it does not run on macOS Catalina. I thought about running it instead on Waterloo’s linux server, then I realized as a student I do not have the root access. Since it seems like there are no better tools other than this, my final workaround is to run this on Azure, which is a nice service provided by Microsoft.

I have provided all codes & bash commands used in the process, if Valgrind is something you need you can just follow this post step by step.

Let’s get started.

Setting up Azure

Since the platform is Mac so first we use brew to install azure-cli, then creates a vm on our machine.

$ brew update && brew install azure-cli
$ az login
$ az group create --name myResources --location eastus
$ az vm create --resource-group myResources \
  --name myVM \
  --image UbuntuLTS \
  --ssh-key-values ~/.ssh/id_rsa.pub \
  --output json \
  --verbose

Now the result would look like this :

{
  "fqdns": "",
  "id": "...",
  "location": "eastus",
  "macAddress": "...",
  "powerState": "VM running",
  "privateIpAddress": "...",
  "publicIpAddress": PUBLIC_IP_ADDRESS,
  "resourceGroup": "myResources",
  "zones": ""
}

This is the VM created for which publicIpAddress displays the IP address which is used to connect to the VM. So we connect like this:

$ ssh PUBLIC_IP_ADDRESS
kevin@myVM:~$

Use Valgrind

Now we have successfully connected to the Azure server running Ubuntu from our terminal, the next thing we need to do is to actually use Valgrind. (Note: since many of the fundamental softwares such as make or gcc are not installed on the server, instead of install each of them manually I simply used build-essential, which includes everything we need)

$ sudo apt-get -y update
$ sudo apt-get install build-essential
$ sudo apt-get install valgrind
$ mkdir valgrindtest
$ cd valgrindtest
$ vi main.cpp

Just to simply test Valgrind’s ability, we write something like this:

// main.cpp
# include “stdlib.h

int main(void) {
  int* x = (int *) malloc(100 * sizeof(int));
}

This piece of close clearly demonstrates a leak of 100 * sizeof(int). If we apply Valgrind to check it, we would need to do this:

$ g++ main.cpp -o main
$ valgrind --tool=memcheck --leak-check=full --show-reachable=yes --log-file=“result” ./main

This command runs the main executable we just generated and output the result to a file named result. If we open this file, we would see this:

==114005== Memcheck, a memory error detector
==114005== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==114005== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==114005== Command: ./main
==114005== Parent PID: 110811
==114005==
==114005==
==114005== HEAP SUMMARY:
==114005==     in use at exit: 400 bytes in 1 blocks
==114005==   total heap usage: 1 allocs, 0 frees, 400 bytes allocated
==114005==
==114005== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==114005==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==114005==    by 0x10865B: main (in /home/kevin/valgrind_test/main)
==114005==
==114005== LEAK SUMMARY:
==114005==    definitely lost: 400 bytes in 1 blocks
==114005==    indirectly lost: 0 bytes in 0 blocks
==114005==      possibly lost: 0 bytes in 0 blocks
==114005==    still reachable: 0 bytes in 0 blocks
==114005==         suppressed: 0 bytes in 0 blocks
==114005==
==114005== For counts of detected and suppressed errors, rerun with: -v
==114005== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

We know an int has the size of 4 bytes, so a lost of 400 bytes makes sense. Now, if we correctly handles the pointer by freeing it at the end before the program terminates:

==114735== Command: ./main
==114735== Parent PID: 110811
==114735==
==114735==
==114735== HEAP SUMMARY:
==114735==     in use at exit: 0 bytes in 0 blocks
==114735==   total heap usage: 1 allocs, 1 frees, 400 bytes allocated
==114735==
==114735== All heap blocks were freed -- no leaks are possible
==114735==
==114735== For counts of detected and suppressed errors, rerun with: -v
==114735== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

We can see now Valgrind tells us that no leaks are possible, which is what we wanted.

So, next time before I’m handing in my project, I would just throw all my code on this server and runs Valgrind on all test cases to make sure no memory is leaked.

Thanks for reading, I hope this helps.