I am trying to optimize a problem using OpenACC, however, there are some basic functions that are set as routines. The main problem I am facing is with the calloc function where it shows the following error at the end:
ptxas fatal : Unresolved extern function 'calloc'
The command for compiling used is:
pgcc acc.c -acc -Minfo=accel -ta=nvidia:cc60,nordc -o acc
I previously tried without the nordc flag, however, there was this error:
nvlink error : Undefined reference to 'calloc' in '/tmp/pgccqWXdW9NTZXUL.o'
nvlink error : Undefined reference to 'rand' in '/tmp/pgccqWXdW9NTZXUL.o
Many system calls are not available on the device. While you could replace 'calloc' with 'malloc' which is available, I would highly advise not allocating within device code. Besides being very slow, the device heap is quite small (~32MB). You'll be better off if you can refactor your algorithm to not dynamically allocate data on the device.
For "rand", you'll want to call 'cuRand'. If you are using PGI, we ship examples on how to call cuRand under the "$PGI/2018/examples/CUDA-Libraries/curand" directory. Note that 'rand' is not thread safe so should not be used in a parallel context, host or device.
Related
I am trying to modify the __default_morecore function in malloc/morecore.c. The original __default_morecore is a simple wrapper for sbrk, but I want to use shm_open function inside __default_morecore to create shared memory object. Here is the malloc/morecore.c code I modified:
...
/* Include header files for shm_open */
void *
__default_morecore (ptrdiff_t increment)
{
int shm_fd;
/* Create the shared memory object */
shm_fd = shm_open(shm_name, O_CREAT | O_RDWR, 0644);
if (shm_fd < 0){
return NULL;
}
...
}
I am pretty sure that my codes are right since I tested the code snippet in a small program and it works. After making this change, it will show below error message when using make for glibc 2.32 sources:
.../build/libc_pic.os: In function '__GI___default_morecore':
.../malloc/morecore.c:69: undefined reference to `shm_open'
collect2: error: ld returned 1 exit status
../Makerules:698: recipe for targe '.../build/libc.so' failed
I searched online for this error, and it's typically becasue doesn't link with -lrt. I tried add -lrt in 'LDFLAGS' and 'LIBS' during ../configure, but not working. Then I added -lrt at the end of build-shlib of Makerules (which is used to build libc.so), and the error was changed to be following:
//lib/x86_64-linux-gnu/librt.so.1: undefined reference to `__clock_getcpuclockid#GLIBC_PRIVATE'
//lib/x86_64-linux-gnu/librt.so.1: undefined reference to `__clock_nanosleep#GLIBC_PRIVATE'
//lib/x86_64-linux-gnu/librt.so.1: undefined reference to `__clock_settime#GLIBC_PRIVATE'
//lib/x86_64-linux-gnu/librt.so.1: undefined reference to `__clock_getres#GLIBC_PRIVATE'
//lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `__libc_vfork#GLIBC_PRIVATE'
collect2: error: ld returned 1 exit status
../Rules:215: recipe for target '/home/yifei/FSL_Repos/test_shm_mmap_malloc/glibc-malloc-modified/build/iconv/iconvconfig' failed
The new error shows that multiple symbols from librt.so and libpthread.so are undefined. I tried add -lpthread -lrt to many places in glibc Makefile/Makeconfig/Makerules, but it doesn't work. Also, from the above errors, I found the linking libraries are from my system in-built libraries, not the path of current modified glibc which I am building. Is that an expected behavior? I think it should use the librt.so and libpthread.so in my modified glibc I am building, but I cannot find librt.so, librt.a and libpthread.so in my build folder after the make terminates. Does it mean these are not generated at the stage of the error I occur? If yes, it might be a dependency issue considering I called a glibc function inside glibc. How to resolve that issue?
How can I call shm_open in malloc/morecore.c and link that librt without any error? Thanks!
shm_open is just a thin wrapper around the open function, see sysdeps/posix/shm_open.c. What is problematic is the construction of the file name in the SHM_GET_NAME macro (in sysdeps/posix/shm-directory.h). It calls __shm_directory (from sysdeps/unix/sysv/linux/shm-directory.c), and the current implementation potentially calls malloc under the covers.
I suggest hard-wiring the shared memory segment location to a file in /dev/shm, and call open directly (or rather __open64, otherwise the linknamespace tests will fail during make check).
The __morecore hook is not a complete solution because it only covers part of the main allocation arena used by glibc malloc. If you want to experiment with malloc, it may be easier to start out of with a simple out-of-tree malloc implementation and use the symbol interposition mechanism. But you still need to be careful which glibc functions you call in your interposing malloc.
Trying to use sleep() to pause my program briefly.
Except when I "make" I get an undefined reference to sleep, even though I #include <unistd.h> at the top.
In function `main':
[...]/source/ball.c:232: undefined reference to `sleep'
[...]/source/ball.c:240: undefined reference to `sleep'
collect2: error: ld returned 1 exit status
I'm using linux.
Any suggestions?
Thanks
EDIT: This Is not a duplicate question because every other time this question has been asked, the user was running it on Windows. The solution. for me, is not simply to include the windows header.
EDIT(2): The link to that other question does not help me. That's why I made a new post. I'm not on windows!!
This is a linker error, not a compiler error (you can see that from the "ld returned 1 exit status" part - ld is the linker). So sleep is declared in the header, which compiles fine, but you need to ensure you include the correct library/binary file for the linking stage.
I can roughly replicate the reported behavior with the following program:
#include <unistd.h>
int main (void) {
sleep(1);
return 0;
}
void _start (void) {
asm("call main;"
"mov %eax,%ebx;"
"movl $1,%eax;"
"int $0x80;");
}
But, it must be compiled with -nostdlib. From this TIO example, I get:
/tmp/ccfjKQV4.o: In function `main':
.code.tio.c:(.text+0xa): undefined reference to `sleep'
collect2: error: ld returned 1 exit status
Which pretty closely matches the output you are reporting. To fix this, you need to provide libc when linking the program. This can be accomplished by adding -lc, as demonstrated at this TIO example. But, if you are using -nostdlib, this solution may not be viable (more on that later).
_start
The sample program I provided is an example of how to create an x86 linux program that will call main and then call exit without needing to use the C runtime. Without the standard C runtime, linux will attempt to jump to a routine called _start. Since there is no C library, exit is called via assembly.
-nostdlib
The -nostdlib option is telling the compiler to not include the standard C runtime and C libraries when building the executable. This is sometimes used in embedded software development where the embedded platform has its own runtime. If this software is intended to run on an embedded platform, it may be erroneous to include -lc to the link line, since it may cause interference with embedded system's library. In that case, you may need to implement your own version of sleep or find a different way to pause your program.
I am trying to compile a hello world program in C on a Linux 64-bit machine. I am using an ARM cross compiler to load my application onto an ARM processor. However, when compiling the code using arm-none-eabi-gcc -o hello hello.c I get a series of errors:
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): In function exit':
exit.c:(.text.exit+0x2c): undefined reference to_exit'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): In function _sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to_sbrk'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-writer.o): In function _write_r':
writer.c:(.text._write_r+0x20): undefined reference to_write'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-closer.o): In function _close_r':
closer.c:(.text._close_r+0x18): undefined reference to_close'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-fstatr.o): In function _fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to_fstat'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-isattyr.o): In function _isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to_isatty'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-lseekr.o): In function _lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to_lseek'
/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-readr.o): In function _read_r':
readr.c:(.text._read_r+0x20): undefined reference to_read'
collect2: error: ld returned 1 exit status
When I try compiling by doing: arm-none-eabi-gcc -c hello.c, it creates an object code hello.o which tells me that the compiler runs fine.
Could someone perhaps tell me why my compilation is return such errors please?
UPDATE
I realize now that the C runtime library isn't included in the compilation. Does anyone know of any options I need to include in the compilation or how to link the library to be able to use standard functions such as printf for example?
What should the MCU chip do with a printf string since there is no console? That's what is happening. libc needs low level functions that is platform dependent and shall not be included in the libc.
You need a retarget.c or a syscalls.c file that defines all these missing symbols and properly retarget the printf output to a serial line that you have access from the outside of the chip.
I strongly recommend you to use the yagarto toolkit, they provide a syscall.c file with what's necessary to build a project when linking against libc, as you are doing.
If you want to try the short path, include the syscall.c file to your project and reprogram its functions internals to suit your needs.
Linking bare gcc toolchain against libc in the microcontroller world is not for beginners. My recommendation is always to follow step by step yagarto's tutorials.
Iam writing a program in C. Is there any way(gcc options) to identify the unused code and functions during compilation time.
If you use -Wunused-function, you will get warnings about unused functions. (Note that this is also enabled when you use -Wall).
See http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html for more details.
gcc -Wall will warn you about unused static functions and some other types of unreachable code. It will not warn about unused functions with external linkage, though, since that would make it impossible to write a library.
No, there is no way to do this at compile time. All the compiler does is create object code - it does not know about external code that may or may not call functions you write. Have you ever written a program that calls main? It is the linker that determines if a function (specifically, a symbol) is used in the application. And I think GCC will remove unused symbols by default.
I have used dlsym to create a malloc/calloc wrapper in the efence code as to able to able to access the libc malloc (occassionally apart from efence malloc/calloc). Now when i link it, and run, it gives following error: "RTLD_NEXT used in code not dynamically loaded"
bash-3.2# /tool/devel/usr/bin/gcc -g -L/tool/devel/usr/lib/ efence_time_interval_measurement_test.c -o dev.out -lefence -ldl -lpthread
bash-3.2# export LD_LIBRARY_PATH=/tool/devel/usr/lib/
bash-3.2# ./dev.out
eFence: could not resolve 'calloc' in 'libc.so': RTLD_NEXT used in code not dynamically loaded
Now, if i use "libefence.a" it is happening like this:
bash-3.2# /tool/devel/usr/bin/gcc -g -L/tool/devel/usr/lib/ -static
efence_time_interval_measurement_test.c -o dev.out -lefence -ldl -lpthread
/tool/devel/usr/lib//libefence.a(page.o): In function `stringErrorReport':
/home/raj/eFence/BUILD/electric-fence-2.1.13/page.c:50: warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead
/home/raj/eFence/BUILD/electric-fence-2.1.13/page.c:50: warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead
/tool/devel/usr/lib//libc.a(malloc.o): In function `__libc_free':
/home/rpmuser/rpmdir/BUILD/glibc-2.9/malloc/malloc.c:3595: multiple definition of `free'
/tool/devel/usr/lib//libefence.a(efence.o):/home/raj/eFence/BUILD/electric-fence-2.1.13/efence.c:790: first defined here
/tool/devel/usr/lib//libc.a(malloc.o): In function `__libc_malloc':
/home/rpmuser/rpmdir/BUILD/glibc-2.9/malloc/malloc.c:3551: multiple definition of `malloc'
/tool/devel/usr/lib//libefence.a(efence.o):/home/raj/eFence/BUILD/electric-fence-2.1.13/efence.c:994: first defined here
/tool/devel/usr/lib//libc.a(malloc.o): In function `__libc_realloc':
/home/rpmuser/rpmdir/BUILD/glibc-2.9/malloc/malloc.c:3647: multiple definition of `realloc'
/tool/devel/usr/lib//libefence.a(efence.o):/home/raj/eFence/BUILD/electric-fence-2.1.13/efence.c:916: first defined here
Please help me. Is there any problem in linking?
NO ONE IN STACK OVERFLOW WHO CAN RESOLVE THIS
The problem is with your question, not with us ;-)
First off, efence is most likely the wrong tool to use on a Linux system. For most bugs that efence can find, Valgrind can find them and describe them to you (so you could fix them) much more accurately. The only good reason for you to use efence is if your application runs for many hours, and Valgrind is too slow.
Second, efence is not intended to work with static linking, so the errors you get with -static flag are not at all surprising.
Last, you didn't tell us what libc is installed on your system (in /lib), and what libraries are present in /tool/devel/usr/lib/. It is exceedingly likely that there is libc.so.6 present in /usr/devel/usr/lib, and that its version does not match the one installed in /lib.
That would explain the RTLD_NEXT used in code not dynamically loaded error. The problem is that glibc consists of multiple binaries, which all must match exactly. If the system has e.g. libc-2.7 installed, then you are using /lib/ld-linux.so.2 from glibc-2.7 (the dynamic loader is hard-coded into every executable and is not affected by environment variables), and mixing it with libc.so.6 from glibc-2.9. The usual result of doing this is a SIGSEGV, weird unresolved symbol errors, and other errors that make no sense.