troubleshoot wrong file permissions - gdb

I have a process that creates a log file, with file permissions 644. However, when I run the process loading a specific shared object library using LD_PRELOAD, the file permissions are set to 2101(specifically the setgid permission is set). I do not have the source code for the program that creates the process, but I do have the source code for the .so file. I know for sure that the file permissions are a result of the .so file being loaded, because when I load the .so file for a program(that I wrote) that creates a file, the file permissions have the setuid/setgid bit set. I tried using gdb for the program I wrote but I am not able to step through the code. I just get a segmentation fault error the moment I start the program with the .so file loaded using gdb. How should I troubleshoot this problem? I don't see any file permissions being set in the source code of the .so file. The program I wrote is very simple, it looks something like this -
#include <stdio.h>
int main(){
printf(" This is my program");
system("touch /tmp/myfile.txt");
return(0);
}

I don't see any file permissions being set in the source code of the .so file.
Does your .so interpose open?
One way to create files with "random" permissions is to (incorrectly) interpose open like so:
int open(const char *fname, int flags)
{
... do whatever
return real_open(fname, flags); // problem: omits 3rd argument to open
// and passes "garbage" permissions when
// O_CREATE is in flags.
}
I just get a segmentation fault error the moment I start the program with the .so file loaded using gdb.
When GDB runs your program, it invokes $SHELL (to take care of any input/output redirection). Your shell likely doesn't like having its open interposed incorrectly either.

Related

C/C++ project under Visual Studio : Not found resources

When I run the Debug in Visual Studio for a project, fopen function works fine. It tries to open a file contained in the project and that I added in the filter "Resources".
But when I run .EXE file of my project, I get the null pointer exception: 0x000005c.
When I added the file to be in the same directory as my .EXE file, the exception disappeared.
This is the instruction I use :
fopen(&filename, "rb");
I know it is adviced to use fopen_s instead, but the file is not found anyway...
Apparently, the file is searched always in the current directory...
So, how to include the file in .EXE and make the path of the file relative to the .EXE, at a way it will be contained in the .EXE and not added to the directory where there is .EXE?
You can't include the file in the .exe. You just need to make sure that the file is in the same directory as the .exe.
If you really, really want to only use one file, you could either:
Zip the .exe and the text file together and make sure you include in a readme that the text file needs to be in the same location as the .exe
Use an array/struct/some other way of storing the contents of the file in the program itself, and reference that instead of using a file (I assume you don't care about users being able to edit this data outside of an instance of the program since you wanted it bundled with an executable, so the file is unnecessary in that case)
The reason the program only works when you put the file in the directory of the .exe is because the path to the file is defined in the program as something like .\file.txt or file.txt. When the file isn't in the same directory as the .exe, the program will try to find it, and will be unable to, which is why you get the error. It works when you debug because you have a copy of the text file in the same location as the debug .exe.
EDIT: I would also ignore the warnings about fopen_s and other variant's that append a _s to the end of a command - these are windows specific, non-standard, and in most cases, pointless. If you know this program will only be used in windows environments and you're not doing something for school where you are required to write standard code, I suggest you use the _s variants for the sake of security, but it will reduce portability of your code.

Open a file in current directory

I'm trying to open a file where my program runs, I could open a file in directories like this:
myfile.open("D:\\users.txt");
But I want to open this file:
myfile.open("users.txt");
users.txt is placed where my program is.
users.txt is placed where my program is.
The current working directory of your process may not be where your program executable is. The two are not bound together.
This:
myfile.open("users.txt");
should work just fine. However, I have encountered situations where the program could not read the file. That was due to the white spaces being included within the full path:
eg: "C:\Folder1\Folder 2\file.txt"
Make sure you don't have any white spaces there...
I recommend reading up on Naming Files, Paths, and Namespaces to give you a better understanding how Win32 API handles File paths, and also Namespaces. It will help you in the long run when you need to open USB and Serial connections to external devices.

Fortran Open from current directory

I am writing a fortran program and I would like to know if it is possible to open a file from the same directory where the program itself is placed.
I am using Ubuntu 12.04 BTW.
For example, if I put the compiled program at the directory "/home/username/foo" I would like the program to open the file "/home/username/foo/bar.txt" and write "Hello!" in it.
My minimal working example is the following:
program main
implicit none
open(unit=20,file="bar.txt",action="write")
WRITE(20,*) "Hello!"
close(20)
end program main
When I compile using gfortran it opens and writes in the file "/home/username/bar.txt" no matter where I put the program file.
On the other hand, when I compile it for windows (using mingw) making a .exe file and execute it in windows it does what I want, it opens the file where the executable file is placed.
[EDIT] I just found out that if I execute the program by double clicking it, it will open the file in the program directory but when I execute it from Terminal it opens at "/home/username/", so maybe is more about the way I send the command from Terminal, currently I am doing it by the following command "/home/username/foo/myprogram".
I too am running Ubuntu 12.04 with gfortran 4.6.3, but I do not experience this. Where ever it is that I place my executable, there is bar.txt after execution.
That said, if you want a file at a specific place, then declare a character string as follows:
character(26) :: filename
filename="/home/username/foo/bar.txt"
and then open the file as
open(unit=20, file=filename)
and you are home free.
EDIT
I just noticed your edit. I imagine that you open terminal and do not cd to the location of the executable, but run the command for execution. That would indeed cause you to always have the file open in whatever folder you are currently in.

Matlab will not run my C++ .exe file

I have program in C++ that runs great but it has different steps in it. It opens a file first then does some calculations based on the data it gets from the file. Now I'm trying to run it through matlab. I tried mex but it got too complicated because I have VS 2010 Express and MATLAB 2007b. And so mex can never find my c compiler.
I'm now trying to just run it straight from the C++ program executable file. Here's how I tried to do it:
system('C:\path\file.exe')
it would run but the command window freezes and I have to close Matlab every time to get back on track. Then I tried to double click on the executable file it self. It flashes but I can see it outputs something from my file "file could not be uploaded" which is generated by a part of my program if it cant find the file.
So then I realized it's probably because of that that caused it to not run and crash.
So I wrote a sample code to open the file first before the system command open the .exe file. I've done something like fopen('fname','r'), but nothing works. Please note that this file I'm trying to open is a .COF file.
I tried running the .exe file using debug and release modes but nothing happens. It gives no errors which means it sees the .exe file but the command line doesn't come up and matland command window freezes.
After running, it's supposed to prompt the user at the command line then take input arguments and output something...
Please help....
I am guessing that your .COF file is in a different path than what's accessible by your binary. If you can recompile, try an absolute path name, and test it first without MATLAB.
There are more thorough ways to solve this, like passing the filename to your binary as a command line argument, or to read up what the rules are for the "current directory" when you use system, but perhaps you'd be happy with the quick solution.

How to change source path in executable g++

I compile my programs in a compiler machine. Later I run and test the programs in a different environment. If I compile with -fprofile-arcs on then the program tries to write a file in a folder which does not exist in the running environment. Is there a work-around for this problem?
Thanks
Further to RP's answer, I think this would be useful.
if the object file /user/build/foo.o
was built with -fprofile-arcs, the
final executable will try to create
the data file /user/build/foo.gcda
when running on the target system.
This will fail if the corresponding
directory does not exist and it is
unable to create it. This can be
overcome by, for example, setting the
environment as
GCOV_PREFIX=/target/run' and
GCOV_PREFIX_STRIP=1'. Such a setting
will name the data file
/target/run/build/foo.gcda.
Nakiya, According to this
"-fprofile-arcs
Add code so that program flow arcs are instrumented. During execution the program records how many times each branch and call is executed and how many times it is taken or returns. When the compiled program exits it saves this data to a file called auxname.gcda for each source file. The data may be used for profile-directed optimizations (-fbranch-probabilities), or for test coverage analysis (-ftest-coverage). Each object file's auxname is generated from the name of the output file, if explicitly specified and it is not the final executable, otherwise it is the basename of the source file. In both cases any suffix is removed (e.g. foo.gcda for input file dir/foo.c, or dir/foo.gcda for output file specified as -o dir/foo.o)."