Firstly, I want to know how to install TCmalloc in Ubuntu. Then I need a program uses TCmalloc. Then I need a small program to show that TCmalloc is working better than PTmalloc.
I'll provide another answer since there's an easier way to install it than in the other answer:
Ubuntu already has a package for google perf tools: http://packages.ubuntu.com/search?keywords=google-perftools
By installing libgoogle-perftools-dev you should get all that is required for developing tcmalloc applications. As for how to actually use tcmalloc, see the other answer.
Install:
sudo apt-get install google-perftools
Create an application in eclipse or any other code composer
#include <iostream>
#include <unistd.h>
#include <vector>
#include <string>
using namespace std;
class BigNumber
{
public:
BigNumber(int i)
{
cout << "BigNumber(" << i << ")" << endl;
digits = new char[100000];
}
~BigNumber()
{
if (digits != NULL)
delete[] digits;
}
private:
char* digits = NULL;
};
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
vector<BigNumber*> v;
for(int i=0; i< 100; i++)
{
v.push_back(new BigNumber(i));
}
return 0;
}
This code will help you see how memory is leaking
Then add the library to your makefile
-ltcmalloc
when running the application, you want to create a heap file, so you need to add an environment variable HEAPPROFILE=/home/myuser/prefix
and files prefix.0001.heap will be created in the /home/myuser path
Run the application and heap files will be created
Examine heap files
pprof helloworld helloworld.0001.heap --text
Using local file helloworld.
Using local file helloworld.0001.heap.
Total: 9.5 MB
9.5 100.0% 100.0% 9.5 100.0% BigNumber::BigNumber
0.0 0.0% 100.0% 0.0 0.0% __GI__IO_file_doallocate
Easy to see which objects leaked and where were they allocated.
To install TCMalloc:
sudo apt-get install google-perftools
To replace allocators in system-wide manner I edit /etc/environment (or export from /etc/profile, /etc/profile.d/*.sh):
echo "LD_PRELOAD=/usr/lib/libtcmalloc.so.4" | tee -a /etc/environment
To do the same in more narrow scope you can edit ~/.profile, ~/.bashrc, /etc/bashrc, etc.
If you would like to use tcmalloc only just for allocated memory optimization, not for analysis, you can do like this:
sudo apt -y install libgoogle-perftools-dev
cc -O3 -ltcmalloc_minimal -fno-builtin-malloc \
-fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free -o main main.c
tcmalloc is in the google perf tool, installation guide could be found here.
The example is included in the google perf tool
see here, section Performance Notes
Related
For example, I have a test C program that prints all environment variables:
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
int main(void) {
char **env = environ;
while (*env) {
printf("%s\n", *env);
env++;
}
return EXIT_SUCCESS;
}
GitHub upstream
But when I run it in se.py syscall emulation, it does not print anything, so I'm guessing that gem5 has an empty environment set in syscall emulation by default instead of inheriting the host's.
Tested on gem5 872cb227fdc0b4d60acc7840889d567a6936b6e1.
By doing a quick se.py --help | grep -i env we see:
-e ENV, --env=ENV Initialize workload environment from text file.
and so the following works as expected:
printf 'a=b\nc=d\n' > env.sh
se.py -e env.sh
and the test program prints:
a=b
c=d
Trying to use Bash's <() notation does not work however, gem5 really needs that to be placed in regular file, trying that fails with:
IOError: [Errno 2] No such file or directory: '/dev/fd/63'
In my bash script i have:
program=*program_name*
condition=$(which $program 2>/dev/null | grep -v "not found" | wc -l)
if [ $condition -eq 0 ] ; then
echo "$program is not installed";
echo -n *mypass* |sudo -S gem install $program;
fi
First of all, it installs program every time. It shows that program is not installed, but i can use it from terminal.
...then, i need to use this program in my cocoa application, for example
program --help
Using
system([pathToFile UTF8String]);
i get:
path_to_bundle/myBashScript.sh: Permission denied // Where path is in bundle
path_to_folder/myBashScript.sh:line 30: program: command not found // Where path is from other system folder
Using NSTask i get program: command not found every time.
I don't understand why this is happening. And i would like to know how i can use this program in my cocoa app.
So, i have found the solution.
When you're trying to run the custom system program from the cocoa app, you should give the full path to the binary.
The problem is in:
program=*program_name*
*program_name* should be full path to binary, in my case it was /Library/Ruby/Gems/2.0.0/gems/program-version/bin/program
For additional information about installation paths:
https://wiki.haskell.org/Mac_OS_X_Common_Installation_Paths
http://help.rubygems.org/discussions/problems/739-how-to-run-applications-installed-by-gem
I don't have the Mac machine for ios development. Now I am in a learning stage and want to start the ios development on Linux. So is it possible to run the Objective-C Code on Linux environment?
Yes it is possible in Ubuntu to Run the Objective-C code in the following way:
In Ubuntu, Install GNU Objective-C Compiler and the Gnu-step Development Libraries with the following command::
sudo apt-get –y install gobjc gnustep gnustep-devel
Now type the Program given below and save the file with .m extension.
For Example say, hello.m
// 'Hello World' Program in Objective-C
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog (#"Hello, World!");
[pool drain];
return 0;
}
Now Compile the Program with the following command:
gcc $(gnustep-config --objc-flags) -o hello hello.m $(gnustep-config --base-libs)
Or you could write this sample Makefile:
CC := gcc
GNUSTEP_LIBS = $(shell gnustep-config --base-libs)
GNUSTEP_FLAGS = $(shell gnustep-config --objc-flags)
.PHONY = clean all
PROGS = hello class_hello
all: $(PROGS)
%.o: %.m
$(CC) $(GNUSTEP_FLAGS) -c $^
hello: hello.o
$(CC) -o $# $^ $(GNUSTEP_LIBS)
clean:
rm $(PROGS) *.o
And run:
make
Now Run the executable with the following command:
./hello
OUTPUT -> 2014-11-14 15:47:32.628 hello[2786] Hello, World!
The Format of the Output is something like this-
<DATE> <TIME> <NAME OF THE EXECUTABLE[NUMBER]> <ACTUAL OUTPUT>
Unfortunately, in order to develop for iOS you will need OS X on your machine. An alternative involves creating a virtual machine on your computer and installing OS X and XCode on it. I've heard this solution works perfectly fine for people provided their computer can handle it.
More information on creating a "hackintosh" may be found here.
Sure. LLVM/Clang is available as a package for most Linux distributions and is a great environment for learning Objective-C.
However, you're going to hit a wall very quickly. Namely, the iOS (or OS X) development stack -- the frameworks, APIs, and tools -- aren't available for Linux and, thus, you're out of luck the moment you want to do anything graphical.
There are projects -- GNUStep, Cocotron -- that are an implementation of a Cocoa-like set of APIs (derived directly from OpenStep) and those are great to learn, but you still won't be writing real iOS / OS X apps.
Given that there is a file called copystuff in the Resources folder in a an xCode project, and that file reads:
#!/bin/sh
cp -R /Users/someuser/Documents /Users/admin/Desktop
And if this bit of code below is linked to a button in IB ... it will copy the /Users/someuser/Documents directory to /Users/admin when the button is pressed in a Cocoa app... It works when app is launched in an admin account ( using OS X 10.5.x here) ...
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/sh"];
[task setArguments:[NSArray arrayWithObjects:[[NSBundle mainBundle]
pathForResource:#"copystuff" ofType:#"sh"], nil]];
[task launch];
My question is.. is there a way to have NSTask run a script running as root while this code is called from a non-admin account? Or asked another way..can Objective-C be coded to run scripts from say /usr/bin as root from a non-admin account?
I would strongly recommend against using an external script like this. It's much better to do this with NSFileManager and keep this inside of controlled code. But to the question of how to become root, you want to look at Authorization Services. This site will walk you through how to create an application that escalates its privileges, including the appropriate UI elements for it.
If I'm understanding what you want to do, you're trying to have a non-privileged user be able to perform a privileged action without needing to authenticate?
setuid shell scripts are considered a gigantic security risk, so they're disallowed by the kernel. If you want to write a separate executable program, however, you can set the set-user-ID-on-execution or set-group-ID-on-execution bits on it and get the behaviour you want. Be careful, you're now in the land of big potential security problems...
man chmod for more information.
Here's a quick and dirty example:
$ echo "Hello, world!" > file
$ sudo chown root file
$ sudo chmod 600 file
$ cat file
cat: file: Permission denied
But I can write a program:
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
setuid(0);
system("cat file");
return 0;
}
Which can do what we'd like:
$ cc -Wall -o app main.c
$ chown root app
$ chmod 4755 app
$ ./app
Hello, world!
On AIX, I would run:
ar -X32 -t libdb2.a
and check for output to determine if there is a 32-bit object in the archive. Similarly with -X64 for checking for a 64-bit object. However, what about if I'm on another platform, and need to check the archive to see what it has? Usually I'm on Linux when I need to check, but I could just as easily be on Solaris or HP-UX.
I used to check for shr.o and shr_64.o, since that's what's being compiled, but those are starting to show up in actual messages that are in the archives, and thus the reliability of these have dropped to the point where I'm getting false positives.
If anyone has a pointer, preferably something I can do in perl, that'd be great.
I don't think there is an easy way. If you create two AIX archives, one 32-bit and one 64-bit, as follows:
$ cat a.c
int foo (void) { return 42; }
$ xlc -q32 a.c -c -o a32.o
$ xlc -q64 a.c -c -o a64.o
$ ar -X32 cr a32.a a32.o
$ ar -X64 cr a64.a a64.o
you end up with archives that are not in a readable format by the linux ar:
$ file a32.a a64.a
a32.a: archive (big format)
a64.a: archive (big format)
$ ar t a32.a
ar: a32.a: File format not recognized
$ ar t a64.a
ar: a64.a: File format not recognized
I tried using strings to see if anything obvious was in the archives, but found nothing. Your ony remaining option is to build a binutils package targetting AIX (download binutils, configure with option --target=powerpc-ibm-aix5.3, run make and voilà: you've got a tool called powerpc-ibm-aix5.3-ar somewhere in that build tree).
I'd suggest extract one of the .o files from the .a archive, and then running the file command on it. Example:
$ file fortune/fortune.o
fortune/fortune.o: ELF 32-bit MSB relocatable, SPARC, version 1 (SYSV), not stripped
file isn't standard on every system, but can easily be compiled. Alternatively, there are a couple of perl modules which do the same thing as file.
ar offers the p command which prints the file in question. For example:
$ ar p libcurl.a base64.o > /tmp/base64.o
$ file /tmp/base64.o
base64.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
So... I'm one year late, but I just had the exact same problem. Here is how I solved it, I hope it helps someone:
$ ar t mylib.a
myobj1.o
myobj2.o
myobj3.o
$ mkdir /tmp/mylib
$ cp mylib.a /tmp/mylib
$ cd /tmp/mylib
$ ls
mylib.a
$ ar x mylib.a
$ ls
mylib.a
myobj1.o
myobj2.o
myobj3.o
$ file *
Possible outcomes:
mylib.a: current ar archive
myobj1.o: ELF 64-bit (...)
myobj2.o: ELF 64-bit (...)
myobj3.o: ELF 64-bit (...)
OR
mylib.a: current ar archive
myobj1.o: ELF 32-bit (...)
myobj2.o: ELF 32-bit (...)
myobj3.o: ELF 32-bit (...)
Explanation:
An archive library file is just a collection of ".o" files, when you use the "t" argument of ar you list the contents of the archive and when you use the "x" argument of ar you extract them. Type man ar for further instructions.