I have a problem related to the functioning of gcc for the compilation of different files.
My goal would be to have a program (see script1.c) that would load (compile?) The functions from the script2.c and script3.c file on each run.
This is what my scripts should look like (the names (2 main() and 1 init()) of the functions in the script2.c and script3.c files must not be changed).
script1.c:
int main(int argc, char *argv[]){
printf("loaded main() in script1.c\n");
int ret = main(argc, argv); // main() script2.c
if(ret == 0){
init(argc, argv); // init() script3.c
ret = main(argc, argv); // main() script3.c
if(ret == 0){
ret = main(argc, argv); // main() script3.c
}
}
return(ret);
}
script2.c:
int main(int argc, char *argv[]){
printf("loaded main() in script2.c\n");
return(0);
}
script3.c:
void init(int argc, char *argv[]){
...
argv[0] = (char*)strdup("OK");
printf("loaded init() in script3.c\n");
}
int main(int argc, char *argv[]){
...
if(strcmp(argv[0], "OK") == 0){
printf("loaded init() in script3.c\n");
}
return(0);
}
I would like to return :
loaded main() in script1.c
loaded main() in script2.c
loaded init() in script3.c
loaded main() in script3.c
loaded main() in script3.c
I logically have loops on the main() function.
Here are the different methods I was able to try:
Change the name of the main() function of script1.c to _start(), and use the "-Wl,--allow-multiple-definition -nostartfiles" option during compilation.
Result: Error with the main() function of script2.c is logically initialized 2 times.
Use the system() and exec functions in script1.c to compile/run scripts2.c and script3.c.
Result: Error with script3.c which executes the main() function, before the init() function. I would need, I think, a working equivalent of the "-Wl, -init, init" option for this to work.
Add attribute((constructor)) in the init() function so that it is started before the main() of script3.c. The problem, is that in my example, the init() function will be launched 2 times :
Here is an example of something that may resemble what you are trying to do. I have one main function as well as three helper functions, aptly named func1, func2 and func3. They all reside in the same directory. Each function is in their own source file, named after the function for clarity (but the source file name is arbitrary). main(), the program's "entry point", calls func1, then func2; func2, in turn, calls func3. The parameters to main() are faithfully passed on each time, and output.
In a typical program one would also have a header file that contains the function declarations for all three helper functions; but in this small example one can simply write them manually.
func1.c:
#include <stdio.h>
void func1(int argc, char **argv)
{
printf("func1: Called with the following arguments:\n");
for(int i = 0; i<argc; i++)
{
printf("func1, arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
}
printf("func1: Returning\n");
}
func2.c:
#include <stdio.h>
extern void func3(int, char **);
void func2(int argc, char **argv)
{
printf("func2: Calling func3\n");
func3(argc, argv);
printf("func2: returning\n");
}
func3.c
#include <stdio.h>
void func3(int argc, char **argv)
{
printf("func3: Called with the following arguments:\n");
for(int i = 0; i<argc; i++)
{
printf("func3, Arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
}
printf("func3: Returning\n");
}
And main.c:
#include <stdio.h>
extern void func1(int, char **);
extern void func2(int, char **);
int main(int argc, char **argv)
{
printf("main(): Called with the following arguments:\n");
for(int i = 0; i<argc; i++)
{
printf("Arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
}
printf("********* main(): Calling func1 *********\n");
func1(argc, argv);
printf("********* main(): Calling func2 *********\n");
func2(argc, argv);
}
Sample session: Compile with
$ gcc -Wall -o main main.c func1.c func2.c func3.c
and then execute with e.g.
$ ./main 1 2 3
Output:
Arg. 1 (index 0): ->./main<-
Arg. 2 (index 1): ->1<-
Arg. 3 (index 2): ->2<-
Arg. 4 (index 3): ->3<-
********* main(): Calling func1 *********
func1: Called with the following arguments:
func1, arg. 1 (index 0): ->./main<-
func1, arg. 2 (index 1): ->1<-
func1, arg. 3 (index 2): ->2<-
func1, arg. 4 (index 3): ->3<-
func1: Returning
********* main(): Calling func2 *********
func2: Calling func3
func3: Called with the following arguments:
func3, Arg. 1 (index 0): ->./main<-
func3, Arg. 2 (index 1): ->1<-
func3, Arg. 3 (index 2): ->2<-
func3, Arg. 4 (index 3): ->3<-
func3: Returning
func2: returning
You can see that the first argument to the program is put in their by the command shell and C runtime library: It's the string with which the program was called, which is customary, here "./main". Only after that come the explicit command line arguments "1", "2" and "3".
Related
I am trying to write a program where it execs itself N times, and each time it execs itself a value x starting from 1 is incremented. N should be the only argument of the program.
For example:
./exec_test.o 4
will print:
Exec: 1
Exec: 2
Exec: 3
Exec: 4
Execs done
I only succeeded in making my values decrease from 4 instead of increase to 4:
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** args){
if (argc<2){ //Argument error handling
fprintf(stderr,"Usage %s number_of_iter",args[0]);
exit(EXIT_FAILURE);
}
int x = atoi(args[1]); //x = the argument used when executing
*args[1]-=1; //decrement the argument value
if (x>0){
printf("Exec : %d \n",x); //printing current argument
execv(args[0],args); //exec itself with argument decremented
perror(args[0]);
exit(1);
}
printf("Execs done \n");
}
and executing it results in this:
Exec: 4
Exec: 3
Exec: 2
Exec: 1
Execs done
Is it possible to make x increment from 1 instead of decrease from N while using only one argument for the program?
Yes. You can hold two information (current and maximum count) in one argument.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** args){
if (argc<2){ //Argument error handling
fprintf(stderr,"Usage %s number_of_iter",args[0]);
exit(EXIT_FAILURE);
}
int max, x = 1; // set x to 1 for the first iteration (it will fail to read x)
char next_argument[128];
char* next_args[3];
sscanf(args[1], "%d_%d", &max, &x);
if (x <= max){
printf("Exec : %d \n",x); //printing current argument
// create next argument
snprintf(next_argument, sizeof(next_argument), "%d_%d", max, x + 1);
next_args[0] = args[0];
next_args[1] = next_argument;
next_args[2] = NULL;
execv(args[0],next_args); //exec itself with argument incremented
perror(args[0]);
exit(1);
}
printf("Execs done \n");
}
I wrote a short program in C with OpenMP pragma, and I need to know to which libGOMP function a pragma is translated by GCC.
Here is my marvelous code:
#include <stdio.h>
#include "omp.h"
int main(int argc, char** argv)
{
int k = 0;
#pragma omp parallel private(k) num_threads(4)
{
k = omp_get_thread_num();
printf("Hello World from %d !\n", k);
}
return 0;
}
In order to generate intermediate language from GCC v8.2.0, I compiled this program with the following command:
gcc -fopenmp -o hello.exe hello.c -fdump-tree-ompexp
And the result is given by:
;; Function main (main, funcdef_no=0, decl_uid=2694, cgraph_uid=0, symbol_order=0)
OMP region tree
bb 2: gimple_omp_parallel
bb 3: GIMPLE_OMP_RETURN
Added new low gimple function main._omp_fn.0 to callgraph
Introduced new external node (omp_get_thread_num/2).
Introduced new external node (printf/3).
;; Function main._omp_fn.0 (main._omp_fn.0, funcdef_no=1, decl_uid=2700, cgraph_uid=1, symbol_order=1)
main._omp_fn.0 (void * .omp_data_i)
{
int k;
<bb 6> :
<bb 3> :
k = omp_get_thread_num ();
printf ("Hello World from %d !\n", k);
return;
}
;; Function main (main, funcdef_no=0, decl_uid=2694, cgraph_uid=0, symbol_order=0)
Merging blocks 2 and 7
Merging blocks 2 and 4
main (int argc, char * * argv)
{
int k;
int D.2698;
<bb 2> :
k = 0;
__builtin_GOMP_parallel (main._omp_fn.0, 0B, 4, 0);
D.2698 = 0;
<bb 3> :
<L0>:
return D.2698;
}
The function call to "__builtin_GOMP_parallel" is what it interest me. So, I looked at the source code of the libGOMP from GCC.
However, the only function calls I found was (from parallel.c file):
GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads)
GOMP_parallel_end (void)
So, I can imiagine that, in a certain manner, the call to "__builtin_GOMP_parallel" is transformed to GOMP_parallel_start and GOMP_parallel_end.
How can I be sure of this assumption ? How can I found the translation from the builtin function to the two other ones I found in the source code ?
Thank you
You almost got it. __builtin_GOMP_parallel is just a compiler alias to GOMP_parallel (defined in omp-builtins.def) which is translated very late in compilation, you can see the actual call in the assembly with gcc -S.
GOMP_parallel is similar to
GOMP_parallel_start(...);
fn(...);
GOMP_parallel_end();
I am following a source code on my documents, but I encounter an error when I try to use MPI_Send() and MPI_Recv() from Open MPI library.
I have googled and read some threads in this site but I can not find the solution to resolve my error.
This is my error:
mca_oob_tcp_msg_recv: readv faled : Unknown error (108)
Here is details image:
And this is the code that I'm following:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argv, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0/n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
I commented all of MPI_Send(), and MPI_Recv(), and my program worked. In other hand, I commented either MPI_Send() or MPI_Recv(), and I still got that error. So I think the problem are MPI_Send() and MPI_Recv() functions.
P.S.: I'm using Open MPI v1.6 on Windows 8.1 OS.
You pass in the wrong arguments to MPI_Init (two times argv, instead of argc and argv once each).
The sends and receives actually look fine, I think. But there is also one typo in one of your prints with a /n instead of \n.
Here is what works for me (on MacOSX, though):
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0\n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
If this does not work, I'd guess your OS does not let the processes communicate with each other via the method chosen by OpenMPI.
Set MPI_STATUS_IGNORED instead of &status in MPI_Recv in both places.
I'm learning Pthreads. My code executes the way I want it to, I'm able to use it. But it gives me a warning on compilation.
I compile using:
gcc test.c -o test -pthread
with GCC 4.8.1. And I get the warning
test.c: In function ‘main’:
test.c:39:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
pthread_create(&(tid[i]), &attr, runner, (void *) i);
^
test.c: In function ‘runner’:
test.c:54:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int threadnumber = (int) param;
^
This error comes for the following code:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_THREADS 10
int sum; /* this data is shared by the thread(s) */
void *runner(void * param);
int main(int argc, char *argv[])
{
int num_threads, i;
pthread_t tid[MAX_THREADS]; /* the thread identifiers */
pthread_attr_t attr; /* set of thread attributes */
if (argc != 2) {
fprintf(stderr, "usage: test <integer value>\n");
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) <= 0) {
fprintf(stderr,"%d must be > 0\n", atoi(argv[1]));
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) > MAX_THREADS) {
fprintf(stderr,"%d must be <= %d\n", atoi(argv[1]), MAX_THREADS);
exit(EXIT_FAILURE);
}
num_threads = atoi(argv[1]);
printf("The number of threads is %d\n", num_threads);
/* get the default attributes */
pthread_attr_init(&attr);
/* create the threads */
for (i=0; i<num_threads; i++) {
pthread_create(&(tid[i]), &attr, runner, (void *) i);
printf("Creating thread number %d, tid=%lu \n", i, tid[i]);
}
/* now wait for the threads to exit */
for (i=0; i<num_threads; i++) {
pthread_join(tid[i],NULL);
}
return 0;
}
/* The thread will begin control in this function */
void *runner(void * param)
{
int i;
int threadnumber = (int) param;
for (i=0; i<1000; i++) printf("Thread number=%d, i=%d\n", threadnumber, i);
pthread_exit(0);
}
How can I fix this warning?
A quick hacky fix might just to cast to long instead of int. On a lot of systems, sizeof(long) == sizeof(void *).
A better idea might be to use intptr_t.
int threadnumber = (intptr_t) param;
and
pthread_create(&(tid[i]), &attr, runner, (void *)(intptr_t)i);
pthread_create(&(tid[i]), &attr, runner, (void *) i);
You are passing the local variable i as an argument for runner, sizeof(void*) == 8 and sizeof(int) == 4 (64 bits).
If you want to pass i, you should wrap it as a pointer or something:
void *runner(void * param) {
int id = *((int*)param);
delete param;
}
int tid = new int; *tid = i;
pthread_create(&(tid[i]), &attr, runner, tid);
You may just want i, and in that case, the following should be safe (but far from recommended):
void *runner(void * param) {
int id = (int)param;
}
pthread_create(&(tid[i]), &attr, runner, (void*)(unsigned long long)(i));
I was also getting the same warning. So to resolve my warning I converted int to long and then this warning just vanished. And about the warning "cast to pointer from integer of different size" you can leave this warning because a pointer can hold the value of any variable because pointer in 64x is of 64 bit and in 32x is of 32 bit.
Try passing
pthread_create(&(tid[i]), &attr, runner, (void*)&i);
good afternoon.
I got the code below on a book. I'm trying to execute it, but I don't know what is the "first" and "last" parameters on the MakeCodeWritable function, or where I can find them. Someone can help? This code is about C obfuscation method. I'm using Xcode program and LLVM GCC 4.2 compiler.
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
typedef unsigned int uint32;
typedef char* caddr_t;
typedef uint32* waddr_t;
#define Tam_celula 64
#define ALIGN __attribute__((aligned(Tam_celula)))
void makeCodeWritable(char* first, char* last) {
char* firstpage = first - ((int)first % getpagesize());
char* lastpage = last - ((int)last % getpagesize());
int pages = (lastpage-firstpage)/getpagesize()+1;
if (mprotect(firstpage,pages*getpagesize(), PROT_READ|PROT_EXEC|PROT_WRITE)==-1) perror("mprotect");
}
void xor(caddr_t from, caddr_t to, int len){
int i;
for(i=0;i<len;i++){
*to ^= *from; from++; to++;
} }
void swap(caddr_t from, caddr_t to, int len){
int i;
for(i=0;i<len;i++){
char t = *from; *from = *to; *to = t; from++; to++;
} }
#define CELLSIZE 64
#define ALIGN asm volatile (".align 64\n");
void P() {
static int firsttime=1; if (firsttime) {
xor(&&cell5,&&cell2,CELLSIZE);
xor(&&cell0,&&cell3,CELLSIZE);
swap(&&cell1,&&cell4,CELLSIZE);
firsttime = 0; }
char* a[] = {&&align0,&&align1,&&align2,&&align3,&&align4,&&align5};
char*next[] ={&&cell0,&&cell1,&&cell2,&&cell3, &&cell4,&&cell5};
goto *next[0];
align0: ALIGN
cell0: printf("SPGM0\n");
xor(&&cell0,&&cell3,3*CELLSIZE);
goto *next[3];
align1: ALIGN
cell1: printf("SPGM2\n"); xor(&&cell0,&&cell3,3*CELLSIZE);
goto *next[4];
align2: ALIGN
cell2: printf("SPGM4\n"); xor(&&cell0,&&cell3,3*CELLSIZE);
goto *next[5];
align3: ALIGN
cell3: printf("SPGM1\n"); xor(&&cell3,&&cell0,3*CELLSIZE);
goto *next[1];
align4: ALIGN
cell4: printf("SPGM3\n"); xor(&&cell3,&&cell0,3*CELLSIZE);
goto *next[2];
align5: ALIGN
cell5: printf("SPGM5\n");
xor(&&cell3,&&cell0,3*CELLSIZE);
}
int main (int argc, char *argv[]) {
makeCodeWritable(...);
P(); P();
}
The first argument should be (char *)P, because it looks like you want to modify code inside function P. The second argument is the ending address of function P. You can first compile the code, and using objdump -d to see the address of beginning and end of P, then calculate the size of the function, SIZE, then manually specify in the makeCodeWritable( (char *)P, ((char *)P) + SIZE.
The second way is utilizing the as to get the size of function P, but it depends on the assembler language on your platform. This is code snipe I modified from your code, it should be able to compile and run in x86, x86_64 in GCC 4.x on Linux platform.
align5: ALIGN
cell5: printf("SPGM5\n");
xor(&&cell3,&&cell0,3*CELLSIZE);
// adding an label to the end of function P to assembly code
asm ("END_P: \n");
;
}
extern char __sizeof__myfunc[];
int main (int argc, char *argv[]) {
// calculate the code size, ending - starting address of P
asm (" __sizeof__myfunc = END_P-P \n");
// you can see the code size of P
printf("code size is %d\n", (unsigned)__sizeof__myfunc);
makeCodeWritable( (char*)P, ((char *)P) + (unsigned)__sizeof__myfunc);
P(); P();
}
With some modification to support LLVM GCC and as in Mac OS X
int main (int argc, char *argv[]) {
size_t sizeof__myfunc = 0;
asm volatile ("movq $(_END_P - _P),%0;"
: "=r" (sizeof__myfunc)
: );
printf("%d\n", sizeof__myfunc);