How to pass environment variables to a gem5 syscall emulation simulation? - gem5

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'

Related

How to use g++ without Makefile to build cpp that makes calls to other header files?

I am trying to build at the command prompt the following:
g++ -c ../../TRUNK/StringUtl.cpp -o StringUtl.o // ok
g++ -c ../../TRUNK/CircularBuf.cpp -o CircularBuf.o // ok
g++ -c ../../TRUNK/UartComm.cpp -o UartComm.o // fatal error: CircularBuf.h: No such file or directory THE header to his cpp file has #include "CircularBuf.h"
UartComm.h: contents at the top of file
//---------------------------------------------------------------------------------------
// General inclusions
//---------------------------------------------------------------------------------------
#include <stdio.h>
#include "CircularBufClass.h"
This error is beacuse g++ is not able to find the header files. You would need to provide path of your header files using -I<Path> option.
Eg:
g++ -Iyourheaderfilepath/ -c ../../TRUNK/UartComm.cpp -o UartComm.o

Setting argv[0] for a valgrind child process?

Is there any way to override the argv[0] specified by valgrind when it execve's the child process?
Why?
I'm using Valgrind with a tool that examines its argv[0] to determine the location of its executable in order to find related executables relative to itself. It exec()s a lot of children, most of which are not of any interest and should not be traced by Valgrind.
I can intercept invocations of the commands of interest by populating a directory with wrapper scripts that call the next executable of the same name on the PATH under the control of valgrind. But valgrind always sets argv[0] to the concrete name of the executable it invoked. I want it to pass the name of the wrapper executable instead, so the child command looks in my wrapper directory for related commands to run.
The usual workaround would be to create a symlink to the real executable from the wrapper dir, then invoke the real executable via the symlink. But that won't work here because that's where the wrapper scripts must exist.
Ugly workaround
So far the only solution I see is to re-exec my wrapper script under valgrind, detect that the wrapper script is running under valgrind, and exec the real target program without wrapping when the script detects it's already running under valgrind. That'll work, but it's ugly. It requires that valgrind --trace-children=yes in order to inspect the actual target, which for my use case is undesirable. And it's expensive to have those short-lived valgrind commands run each wrapper script a second time.
Things I tried
I've tried exec -a /path/to/wrapper/command valgrind /path/to/real/command (bash). But valgrind doesn't seem to notice or care that argv[0] isn't valgrind, and does not pass that on to the child process.
Sample wrapper script with hacky workaround
if [ "${RUNNING_UNDER_VALGRIND:-0}" -eq 0 ]; then
# Find the real executable that's next on the PATH. But don't run it
# yet; instead put its path in the environment so it's available
# when we re-exec ourselves under valgrind.
export NEXT_EXEC="$(type -pafP $mycmd | awk '{ if (NR == 2) { print; exit; } }')"
# Re-exec this wrapper under valgrind's control. Valgrind ignores
# argv[0] so there's no way to directly run NEXT_EXEC under valgrind
# and set its argv[0] to point to our $0.
#
RUNNING_UNDER_VALGRIND=1 exec valgrind --tool=memcheck --trace-children=yes "$0" "$#"
else
# We're under valgrind, so exec the real executable that's next on the
# PATH with an argv[0] that points to this wrapper, so it looks here for
# peer executables when it wants to exec them. We looked up NEXT_EXEC
# in our previous life and put it in the environment.
#
exec -a "$0" "${NEXT_EXEC}" "$#"
fi
Yes that's gross. It'd be possible to make a C executable that did the same thing a bit quicker, but the same issues apply with having to trace children, getting unwanted extra logs, etc.
Edit:
This works, so long as your target program(s) don't care about the executable name itself, only the directory.
NEXT_EXEC="$(type -pafP $mycmd | awk '{ if (NR == 2) { print; exit; } }')"
if ! [ "${0}.real" -ef "${NEXT_EXEC}" ]; then
rm -f "${0}.real"
ln "${NEXT_EXEC}" "${0}.real"
fi
exec valgrind --trace-children=no "${0}.real" "$#"
Edit 2
Beginnings of a valgrind patch to add support for a --with-argv0 argument. When passed, valgrind core will treat the first argument after the executable name as the argv[0] to supply in the target's command line. Normally it puts the executable name there, and treats the client argument list as starting at argv[1].

RISCV C to hex Compilation for UART

I am trying to convert UART loopback program to corresponding hex code. The command
riscv32-unknown-elf-gcc test.c -march=rv32im
riscv32-unknown-elf-gcc -o test test.c
both the command giving error
test.c:2:10: fatal error: rt/rt_api.h: No such file or directory
#include <rt/rt_api.h>
^~~~~~~~~~~~~
compilation terminated.
what is the exact command for compiling the c code with APIs, I am using Pulppissimo toolchain..
my program is
https://github.com/pulp-platform/pulp-rt-examples/tree/master/periph/uart/loopback
You have this error because rt/rt_api.h is not present in your riscv gcc search path.
To see the folders present in search path you can add -v option to your command or use:
riscv32-unknown-elf-cpp -v /dev/null /dev/null
What you can do is find the location of rt/rt_api.h and giving the path you find to gcc. Your command will be:
riscv32-unknown-elf-gcc -o test test.c -Ipath

Objective-C Environment Setup For Ubuntu-Linux

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.

How To Use TCMalloc?

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