clang analyzer memory leaks - linux

Why doesn't clang/clang-analyzer catch that I forgot to free a and have a memory leak? It's obvious. I looked at the man pages and i'm not sure what flags are required.
$ scan-build clang++ -std=c++11 a.cpp
scan-build: Using '/usr/bin/clang' for static analysis
scan-build: Removing directory '/tmp/scan-build-2013-10-02-2' because it contains no reports.
$ cat ./a.cpp
#include <iostream>
int main() {
int *a = new int;
*a = 8;
std::cout<< a << std::endl;
}

Related

C++ string concatenation in the Windows Subsystem for Linux (WSL) is deleting first string

I need help understanding what is wrong with my code or system. For some reason, when compiled and ran in WSL(Windows Subsystem for Linux), the following code generates a wrong result. When ran directly in the windows command terminal, it correctly generates the final output as HNDPNV and in WSL generates PNV. The airports file is simply a series of 50 lines, with 3 letters per line. g++ version is 7.5.0 in ubuntu 18.04 WSL and g++ windows version is 9.2.0.
compilation flags are: g++ -std=c++17 -Wall -Wextra -o test test.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>
using namespace std;
int main() {
string airport_designations[50];
string air_companies_designations[20];
ifstream airports;
ifstream aircompanies;
string name = "apple";
string name2 = "orange";
airports.open("Airports.txt");
for (int i = 0; i < 50; i++){
getline(airports, airport_designations[i]);
cout << airport_designations[i] << endl;
}
airports.close();
aircompanies.open("Companies.txt");
for (int i = 0; i < 20; i++){
getline(aircompanies, air_companies_designations[i]);
cout << air_companies_designations[i] << endl;
}
aircompanies.close();
name = airport_designations[4];
cout << name << endl;
name += airport_designations[8];
cout << name << endl;
}
The line break on windows is \r\n,
On Linux \n.
To get a consistent conclusion, you need to replace all \r\ n in the Airports.txt file with \n.

calling std::system with parameter containing space in double quotes

I need to call a linux std::system call with parameter than contain string with spaces. In order to process it correctly using argc / argv I want to pass it with double quotes.
std::string cmdline = "myprogram -d \"I am a sting\"" ;
if I cout this string I get good results.
When I send it to std::system(cmdline)
and look at ps -ef I get
myprogram -d I am a string
How can I keep "I am a string" as a single parameter for myprogram ?
No problem:
dlaru#IKH-LAPTOP /cygdrive/c/Users/dlaru
$ cat test.cpp
#include <iostream>
#include <string>
#include <cstdlib>
int main()
{
std::string cmdline = "./see \"I am a string\"";
std::cout << cmdline << std::endl;
std::system(cmdline.c_str());
}
dlaru#IKH-LAPTOP /cygdrive/c/Users/dlaru
$ cat see.cpp
#include <iostream>
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
std::cout << argv[i] << std::endl;
}
}
dlaru#IKH-LAPTOP /cygdrive/c/Users/dlaru
$ g++ -std=c++11 test.cpp -o test
dlaru#IKH-LAPTOP /cygdrive/c/Users/dlaru
$ g++ -std=c++11 see.cpp -o see
dlaru#IKH-LAPTOP /cygdrive/c/Users/dlaru
$ ./test
./see "I am a string"
./see
I am a string
(tested in Cygwin)

gperftools cpu profiler does not support multi process?

according to the document, http://gperftools.googlecode.com/svn/trunk/doc/cpuprofile.html, the cpu profiles does support multi process and will generate independent output file:
If your program forks, the children will also be profiled (since they
inherit the same CPUPROFILE setting). Each process is profiled
separately; to distinguish the child profiles from the parent profile
and from each other, all children will have their process-id appended
to the CPUPROFILE name.
but when I try as follow:
// main_cmd_argv.cpp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <gperftools/profiler.h>
int loop(int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sum = i + j;
if (sum %3 == 0) {
sum /= 3;
}
}
}
return 0;
}
int main(int argc, char* argv[]) {
printf("%s\n%s\n", getenv("CPUPROFILE"), getenv("CPUPROFILESIGNAL"));
if (argc > 1 && strcmp(argv[1], "-s")==0) {
// single process
loop(100000);
printf("stoped\n");
} else if (argc > 1 && strcmp(argv[1], "-m")==0) {
// multi process
pid_t pid = fork();
if (pid < 0) {
printf("fork error\n");
return -1;
}
if (pid == 0) {
loop(100000);
printf("child stoped\n");
} else if (pid > 0) {
loop(10000);
printf("father stoped\n");
wait(NULL);
}
}
return 0;
}
// makefile
GPerfTools=/home/adenzhang/tools/gperftools
CCFLAGS=-fno-omit-frame-pointer -g -Wall
ALL_BINS=main_cmd_argv
all:$(ALL_BINS)
main_cmd_argv:main_cmd_argv.o
g++ $(CCFLAGS) -o $# $^ -L./ -L$(GPerfTools)/lib -Wl,-Bdynamic -lprofiler -lunwind
.cpp.o:
g++ $(CCFLAGS) -c -I./ -I$(GPerfTools)/include -fPIC -o $# $<
clean:
rm -f $(ALL_BINS) *.o *.prof
// shell command
$ make
g++ -fno-omit-frame-pointer -g -Wall -c -I./ -I/home/adenzhang/tools/gperftools/include -fPIC -o main_cmd_argv.o main_cmd_argv.cpp
g++ -fno-omit-frame-pointer -g -Wall -o main_cmd_argv main_cmd_argv.o -L./ -L/home/adenzhang/tools/gperftools/lib -Wl,-Bdynamic -lprofiler -lunwind
$ env CPUPROFILE=main_cmd_argv.prof ./main_cmd_argv -s
젩n_cmd_argv.prof
(null)
stoped
PROFILE: interrupts/evictions/bytes = 6686/3564/228416
$ /home/adenzhang/tools/gperftools/bin/pprof --text ./main_cmd_argv ./main_cmd_argv.prof
Using local file ./main_cmd_argv.
Using local file ./main_cmd_argv.prof.
Removing killpg from all stack traces.
Total: 6686 samples
6686 100.0% 100.0% 6686 100.0% loop
0 0.0% 100.0% 6686 100.0% __libc_start_main
0 0.0% 100.0% 6686 100.0% _start
0 0.0% 100.0% 6686 100.0% main
$ rm main_cmd_argv.prof
$ env CPUPROFILE=main_cmd_argv.prof ./main_cmd_argv -m
젩n_cmd_argv.prof
(null)
father stoped
child stoped
PROFILE: interrupts/evictions/bytes = 0/0/64
PROFILE: interrupts/evictions/bytes = 68/36/2624
$ ls
main_cmd_argv main_cmd_argv.cpp main_cmd_argv.o main_cmd_argv.prof Makefile
$ /home/adenzhang/tools/gperftools/bin/pprof --text ./main_cmd_argv ./main_cmd_argv.prof
Using local file ./main_cmd_argv.
Using local file ./main_cmd_argv.prof.
$
It semms that gperf does not support multi process, could anyone please explain? thanks!
Quite old, don't know if you found an answer or not, but...
Seems like every thread/fork should register itself using ProfilerRegisterThread();
You can find more information in those two issues: Here and Here.
Also here is an example code, similar to your test case where the forks can be registered.
I'm currently using gperftools to profile a mpi program and come across this problem. After googling I find that ProfilerStart(_YOUR_PROF_FILE_NAME_) and ProfilerStop() ought be called during every sub-process is executed, and _YOUR_PRO_FILE_NAME_ must be different among different process. Then you could analysis performance of every process.
link(also asked by ZRJ):
https://groups.google.com/forum/#!topic/google-perftools/bmysZILR4ik

Why is there a difference using std::thread::hardware_concurrency() and boost::thread::hardware_concurrency()?

The description of the problem itself is pretty simple. I'm testing the differences of std::thread library in C++11 and boost::thread library.
The output of these:
#include <iostream>
#include <thread>
#include <boost/thread.hpp>
int main() {
std::cout << std::thread::hardware_concurrency() << std::endl;
std::cout << boost::thread::hardware_concurrency() << std::endl;
return 0;
}
gives me different results:
0
4
Why is that?
PS: The version of the gcc package is 4.6.2-1.fc16 (x86_64). I'm using
g++ test.cc -Wall -std=c++0x -lboost_thread-mt -lpthread
After reviewing /usr/include/c++/4.6.2/thread
it can be seen that the implementation is actually:
// Returns a value that hints at the number of hardware thread contexts.
static unsigned int
hardware_concurrency()
{ return 0; }
So problem solved. It's just another feature that hasn't been implemented in gcc 4.6.2
The method employed by your compiler installation of boost is supported for your target, whereas your installation of boost compiler does not support this feature for your target.
TFM says:
The number of hardware threads available on the current system (e.g. number of CPUs or cores or hyperthreading units), or 0 if this information is not available.
EDIT: scratch that, reverse it.
EDIT2: This feature is present on the trunk, but absent in 4.6.2:
~/tmp/gcc-4.6.2/libstdc++-v3/src> wc -l thread.cc
104 thread.cc
~/tmp/gcc-4.6.2/libstdc++-v3/src> grep concurrency thread.cc | wc -l
0
~/tmp/gcc-4.6.2/libstdc++-v3> grep -C 2 VERIFY testsuite/30_threads/thread/members/hardware_concurrency.cc
// Current implementation punts on this.
VERIFY( std::thread::hardware_concurrency() == 0 );
return 0;

Pseudo-random stack pointer under Linux?

I was playing around with some code when I noticed something strange:
[~] main% cat test.cc
#include <stdio.h>
void f()
{
int i;
fprintf(stderr, "&i = 0x%08X\n", (long)&i);
}
int main(int argc, char**argv)
{
f();
}
[~] main% g++ test.cc
[~] main% ./a.out
&i = 0xBFA27AB4
[~] main% ./a.out
&i = 0xBFAD7E24
[~] main% ./a.out
&i = 0xBFCA3464
[~] main% ./a.out
&i = 0xBF96C064
[~] main%
The odd thing to me is the variation in the address of the variable i.
My guess is that the kernel supplies different stack start addresses to try to thwart some kind of crack. What's the real reason?
Address space layout randomisation is used on several operating systems for precisely this reason. Your variation in stack pointer addresses may well be caused by this - very likely to be the case on recent versions of Linux and or *BSD. IIRC recent versions of Windows do this as well.

Resources