Code:
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/wait.h>
#define _GNU_SOURCE
void *stack_memory()
{
const int stackSize = 65536;
void* stack = (void*)malloc(stackSize);
if (stack == NULL) {
printf("%s\n", "Cannot allocate memory \n");
exit(EXIT_FAILURE);
}
return stack;
}
int jail(void *args)
{
printf("Hello !! - child \n");
return EXIT_SUCCESS;
}
int main()
{
printf("%s\n", "Hello, world! - parent");
clone(jail, stack_memory(), SIGCHLD, 0);
return EXIT_SUCCESS;
}
Error:
Undefined symbols for architecture x86_64: "_clone", referenced
from:
_main in docker-4f3ae8.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code
1 (use -v to see invocation)
Linux doesn't prefix symbols with a leading _ so you're not using Linux.
But the clone(2) system call is Linux-specific, according to its man page.
clone() is Linux-specific and should not be used in programs intended
to be portable.
Probably you're using OS X or something. And you're compiling as C, so calling an un-declared function isn't a compile-time error (just a big warning). This is why it's a linker error instead of a compile-time error (and you ignored compiler warnings.)
And BTW, #define _GNU_SOURCE after including header files is pointless. You have to define feature-request macros before including headers to get them to define prototypes for GNU-only functions in cases where that's not already the default.
Related
I'm trying to make a C programm, that will execute subprocesses, which will be interact using semaphore.
Then I compile code, gcc throw referencing error - because it doesn't know about functions "sem_init", "sem_post" and "sem_wait", even though I include semaphore.h library.
Here's how it look:
Code:
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#define LETTER_COUNT 26
#define THREADS 2
char letter[LETTER_COUNT] = "aBCDefghiJklMNoPqrsTuvWxyZ";
pthread_t t[THREADS];
sem_t sem[THREADS];
void print_letter(void) {
//print string
}
void* reorder(void* d) {
(void)d;
//do some work
return NULL;
}
void* switch_case(void* d) {
(void)d;
//do some work
return NULL;
}
int main(void) {
int i;
for(i = 0; i < THREADS; i++) {
if(sem_init(&sem[i], 0, 0) == -1) {
perror("sem_init");
return -1;
}
}
pthread_create(&t[0], NULL, reorder, NULL);
pthread_create(&t[1], NULL, switch_case, NULL);
while(1) {
i = (i + 1) % (THREADS - 1);
sem_post(&sem[i]);
sem_wait(&sem[2]);
print_letter();
sleep(1);
}
return 0;
}
Error:
gcc -Wall task4.c -o task4.o
Undefined first referenced
symbol in file
sem_init /var/tmp//cc0i56ka.o
sem_post /var/tmp//cc0i56ka.o
sem_wait /var/tmp//cc0i56ka.o
ld: fatal: symbol referencing errors. No output written to task4.o
collect2: ld returned 1 exit status
I'm trying to find some information about this problem, but I can't find any working solutions. Maybe I should use some compilation flag (like -lsocket)?
As per man sem_init (and friends)
gcc -Wall task4.c -o task4.o -lpthread
On some system, the 'librt' shared library is built against shared libpthread, and referencing -lrt will imply -lpthread. However the man page indicate the proper command to link is to use -pthread, see below. Note that -pthread will invoke MT semantics, as needed, usually -lpthread, but other libraries, flags or #defines. For example, on GCC/Mint19, it will define -D_REENTRANT.
From man sem_init
AME
sem_init - initialize an unnamed semaphore
SYNOPSIS
#include
int sem_init(sem_t *sem, int pshared, unsigned int value);
Link with -lpthread.
From man gcc
Options Controlling the Preprocessor
-pthread
Define additional macros required for using the POSIX threads library. You should use this option consistently for both compilation
and linking. This option is supported on GNU/Linux targets, most other Unix derivatives, and also on x86 Cygwin and MinGW targets.
Options for Linking
-pthread
Link with the POSIX threads library. This option is supported on GNU/Linux targets, most other Unix derivatives, and also on x86
Cygwin and MinGW targets. On some targets this option also sets flags for the preprocessor, so it should be used consistently for both
compilation and linking.
I run the following code from APUE
#include "apue.h"
#include <sys/wait.h>
void pr_exit(int status)
{
if (WIFEXITED(status))
printf("normal termination, exit status = %d\n",
WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("abnormal termination, signal number = %d%s\n",
WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? " (core file generated)" : "");
#else
"");
#endif
else if (WIFSTOPPED(status))
printf("child stopped, signal number = %d\n",
WSTOPSIG(status));
}
but get error:
$ cc my_wait.c
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I checked multiple times and ensure there no difference with the book's instruction ..
How could I solve the problem?
Transferring a comment into an answer, as requested.
The error message says "there is no function main()", and the source code you show has no function main(), so there's minimal surprise that there's that error message.
Where did you think main() was going to come from?
When you build a program, there needs to be a main() from somewhere, and the standard C library does not provide an implementation. (If you work with Flex or Lex, or Bison or Yacc, you may find minimal main() programs in their libraries, but these are an exception, not the rule.)
I have a lib, called "test.so" that uses functions from two libraries that reference each other. If I call the functions of test.so within a C program, it works just fine, so I assume there's no error in C functions.
However, when I call it from Lua, it throws a Seg Fault error due to an "undefined symbol". The problem is, the symbol is defined, I can see it when I run nm test.so.
Reading the thread below
Lua: C++ modules can't reference eachother, undefined symbol
I tried to creating a new module that would load test.so using dlopen, as described by Rena.
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
#include <dlfcn.h>
int luaopen_drmaa(lua_State *L){
printf("Chamou luaopen_test\n");
if( dlopen("/home/erica/Downloads/test.so", RTLD_NOW | RTLD_GLOBAL) == NULL)
printf("%s\n", dlerror());
else
printf("Chamou dlopen e teve retorno nao null\n");
return 0;
}
I compiled it:
gcc -g drmaa_lib.c -shared -fpic -I /usr/include/lua5.1 -I /usr/local/include/ -L /usr/local/lib/m -llua5.1 -o drmaa.so
But when I run, I get:
$ lua5.1
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require "drmaa"
Chamou luaopen_test
Chamou dlopen e teve retorno nao null
> submitJob()
stdin:1: attempt to call global 'submitJob' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: ?
Then I tried inserting in main function
luaopen_test(L);
and above the main function
extern int luaopen_test(lua_State *L);
to actually open the lib, but I get this error:
$ lua5.1
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require "drmaa"
error loading module 'drmaa' from file './drmaa.so':
./drmaa.so: undefined symbol: luaopen_test
stack traceback:
[C]: ?
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?
The author of the referenced question doesn't show details of the development of the solution.
Does anyone has a clue of what may make it work?
Thanks in advance.
I was obviously doing it wrong, to get the function that actually opens the library I should have used ldsym function. The new code for drmaa lib (the one that loads test.so) is
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
#include <dlfcn.h>
typedef void Register(lua_State*);
int luaopen_drmaa(lua_State *L){
void* lib = dlopen("/home/erica/Downloads/test.so", RTLD_NOW | RTLD_GLOBAL);
if(!lib)
{
printf("%s\n", dlerror());
return 1;
}
Register* loadFunc = (Register*)dlsym(lib, "luaopen_test");
if(!loadFunc)
{
printf("%s\n", dlerror());
return 1;
}
loadFunc(L);
return 0;
}
This answer was base in some code of this thread:
Lua shared object loading with C++ segfaults
This question already has answers here:
Where is clone() method in sched.h on Mac OS X
(2 answers)
Closed 9 years ago.
I would like to use the clone system call on OS X. It's a Unix system call so it shouldn't be a problem, right? I have successfully tried using fork, vfork and other similar functions. Here is the program I'm trying:
#include <sched.h> //Clone resides here
#include <stdlib.h> //standard library
#include <stdio.h>
#include <time.h>
#include <limits.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/types.h>
int helloWorld();
int main(int argc, char *argv[])
{
int (*functionPointer)() = &helloWorld; //The first argument of clone accepts a pointer to a function which must return int
void **childStack = (void**)malloc(1024); //We will give our child 1kB of stack space
clone(functionPointer, childStack, 0, NULL); //First arugment is the function to be called, second one is our stack, CLONE_VM means to share memory, last NULL PID description
return 0;
}
int helloWorld()
{
printf("Hello (clone) world!\r\n");
return 0;
}
Compiling with gcc -o test my_file.c gives:
Undefined symbols for architecture x86_64:
"_clone", referenced from:
_main in ccG3qOjx.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Feel free to ignore the comments, since I'm just learning. And one more thing.. if I try to pass CLONE_VM in the arguments it doesn't even compile giving me the error:
my_file.c: In function ‘main’:
my_file.c:12: error: ‘CLONE_VM’ undeclared (first use in this function)
my_file.c:12: error: (Each undeclared identifier is reported only once
my_file.c:12: error: for each function it appears in.)
Am I missing an #include? If so, which one?
What am I doing wrong and how to fix it?
clone is specific to Linux, so for OS X you're stuck with fork, or use threads if you can manage with that.
I'm getting some problems on compiling a very very simple name.c file on Mac OSX Lion.
Now, I started following Harvard CS50 course on cs50.net. I'm not totally new to programming but I was curious on how this course has been taught.
This is the source of name.c:
#include <stdio.h>
#include <cs50.h>
int
main(void)
{
printf("State your name:\n");
string name = GetString();
printf("O hai, %s!\n", name);
return 0;
}
As you can see, it requires this library: https://manual.cs50.net/CS50_Library.
Now, when I compile it, this happens:
Undefined symbols for architecture x86_64:
"_GetString", referenced from:
_main in name-vAxcar.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [name] Error 1
If I use the same GetString() cs50.c function inside my source file, it works perfectly:
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
typedef char *string;
string GetString(void);
int
main(void)
{
printf("State your name:\n");
string name = GetString();
printf("O hai, %s!\n", name);
}
string
GetString(void)
{
// CODE
}
Why does this happen?
I installed the library as it says on the link above; I checked and both cs50.h and libcs50.a are respectively in /usr/local/include and /usr/local/lib.
Thank you in advance for your help.
The problem you encounter is in the linking stage, not compiling. You did not provide the implementation of GetString, only its declaration (through the .h file you #include).
To provide the implementation itself, you usually need to link against the library which includes it; this is usually done by the -l flag to g++. For example,
g++ file.cpp -lcs50
Your second sample code does link, because you manually (and explicitly) provide an implementation for GetString, though an empty one.