undefined symbol: _open_osfhandle, handle to file descriptor, linking error - c

In a shared library I'm trying to convert a self created handle to a file descriptor so that I can run fsync on that file descriptor. I really have two questions, the first is bellow and the second is if there is some other way to get a file descriptor from a handle.
I include "#include " to my code and then call the code bellow:
int _open_osfhandle(intptr_t oshandle, int flags);
int fd = _open_osfhandle((intptr_t)(handle), 0);
fsync(fd);
This compiles correctly but it does not work when I execute the code I get the following in the logs:
undefined symbol: _open_osfhandle
This usually means there is a linking error when creating the shared library but the correct libraries are linked while compiling the code. io.h is a part of:
rpm -qf /usr/include/sys/io.h
glibc-headers-2.17-105.el7.x86_64
Which should be the standard C library for redhat, which I Included in my ccmake build file:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -pthread")
But I still get the error that the symbol is undefined.
I've tried to work around this by attempting to create my FD with the bellow command but I believe it did not work.
int fd = (uintptr_t)(handle);
Any ideas as to why this issue is coming up.
Also is there some other way for me to get a file descriptor from my created handle?

Related

How to use popen() in a shared library?

When attempting to use popen() in a shared library and preloading it via LD_PRELOAD or /etc/ld.so.preload, the process gets stuck in an infinite loop with either an error message saying that the shared library cannot be preloaded, or the system just freezes and needs to be rebooted, depending on the code.
Please note that compiling not as a shared library (gcc test.c; ./a.out) will work without error.
If it is helpful, I am running a fresh install of Debian on VirtualBox:
Linux debian 3.16.0-4-586 #1 Debian 3.16.36-1+deb8u2 (2016-10-19) i686
GNU/Linux
Okay, so this code:
#define _GNU_SOURCE
#include <stdio.h>
__attribute__((constructor, visibility("hidden")))
void init()
{
FILE *fp = popen("/usr/bin/id", "r");
pclose(fp);
}
Results in the first case:
root#debian:/mnt/group/hcfrk# gcc test.c -o test.so -std=c99 -shared -fPIC
root#debian:/mnt/group/hcfrk# LD_PRELOAD=./test.so whoami
ERROR: ld.so: object './test.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object './test.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object './test.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object './test.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
# For eternity.
This code:
...
#include <limits.h>
...
{
FILE *fp = popen("/usr/bin/id", "r");
if(!fp)
puts("Error.\n");
char buf[PATH_MAX];
while(fgets(buf, sizeof buf, fp))
printf("%s\n", buf);
pclose(fp); // Never gets here: VM just freezes.
}
Results in the second case (the system freezes). I suspect it is because of the while loop not ending and causing pclose() to not be called, as the first code example will freeze the system without pclose() as well.
Any help would be appreciated. Thank you!
Aren't you forkbombing here? Constructor in LD_PRELOAD will cause /usr/bin/id to execute itself forever (as each new instance will get get your library preloaded), most probably halting your machine. You should probably unsetenv before popening.

Undefined reference and bad reloc address when linking to libsndfile

In a project project I am working on, I need to be able to open and read content from audio files (at least WAV files). I installed libsndfile using the Win64 installer from mega-nerd.com, and created a simple C program that opens and closes an audio file to test out the library.
#include <stdio.h>
#include <sndfile.h>
int main()
{
SNDFILE *sndfPtr;
SF_INFO soundfileInfo;
char path[] = "C:\\Users\\jayb\\Documents\\MusicClips\\violin.wav";
printf( "Path: %s\n", path );
/* Open soundfile for reading */
soundfileInfo.format = 0; /* Must be set to zero before opening */
sndfPtr = sf_open( path, SFM_READ, &soundfileInfo );
if( sndfPtr == NULL )
{
fprintf( stderr, "Error: %s\n", sf_strerror(NULL) );
return -1;
}
/* Close soundfile and check for error */
if( sf_close( sndfPtr ) )
{
fprintf( stderr, "There was an error closing the soundfile\n" );
return -1;
}
return 0;
}
However, I keep getting undefined reference errors to the libsndfile functions, plus a bad reloc address error when I try compiling/linking:
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0xbb): undefined reference to `sf_open'
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0xd8): undefined reference to `sf_strerror'
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0x10a): undefined reference to `sf_close'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o: bad reloc address 0x20 in section `.eh_frame'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I'm compiling with this command:
gcc -Wall -o sndfile_test.exe sndfile_test.c -llibsndfile-1
The install of libsndfile comes with header files sndfile.h and sndfile.hh, and .lib, .def, and .dll files: libsndfile-1.lib libsndfile-1.def libsndfile-1.dll
The header and library directories are included in the compiler's search path, and it doesn't seem to be a problem of finding the library? I'm linking the .lib file with -llibsndfile-1 as per instructions on the minGW wiki
I also copied and renamed the .lib file with the .a extension and tried linking with -lsndfile-1 (this worked for someone else having a similar problem), but I get the exact same errors when I do so.
Any help would be appreciated! If I cannot link successfully to libsndfile, are there are any other simple libraries out there I could use for reading from audio files?
Edit: Of course I spend two days trying to find the solution, finally post to stackoverflow, and then solve the problem two hours later. I will post my solution as an answer to the question.
Following the information on this page of the MinGW wiki, use MinGW's dlltool with the libsndfile-1.def file to re-create the the dll's import library.
Use this command to do so:
dlltool -d libsndfile-1.def -l libsndfile-1.dll.a
This will create the .dll.a file that you can use instead of the .lib file. Note that when I did this, the .dll.a file did not appear in the directory I was in when I executed the above command. It ended up hidden in my \AppData directory, so you might have to search your OS for it.
Replace the libsndfile-1.lib in your lib directory with libsndfile-1.dll.a and then compile using:
gcc -Wall -o sndfile_test.exe sndfile_test.c -lsndfile-1

How to use pcap structures with the good includes

Since yesterday i'm learning how to use pcap to parse a pcap file.
And since yesterday i'm getting an error :
Here is my simple code, trying to write the fd in pcap_t structure:
#include <pcap/pcap.h>
#include <sys/types.h>
#include <pcap-bpf.h>
#include <stdio.h>
int main() {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *result;
if ((result = pcap_open_offline("test.pcap", errbuf)) == NULL) {
printf("%s\n", errbuf);
return -1;
}
printf("fd=%d\n", result->fd);
return 0;
}
and here is my error:
gcc -Wextra -Wall -Werror -I./includes -c -o main.o main.c
main.c: In function ‘main’:
main.c:14:27: error: dereferencing pointer to incomplete type
printf("fd=%d\n", result->fd);
^
make: *** [main.o] Error 1
I saw this post: Pcap Incomplete Type
Where the guy is having almost the same problem as I have, but still, I can't find a solution, I included what pcap_open_offline needs, I also included pcap-bpf.h because I saw that pcap_t is using bpf_program.
The first answer is saying "The error is because the compiler cannot see the definition of the structure" but in my case the structure is pcap_t and is typedef in pcap.h, which i included.
I just don't get how to include correclty with pcap.
Also, I'm on Ubuntu, and i cannot find all my .h file about pcap. When I look on google, I only find .h from apple and windows, so I assume that i'm using the same as the apple one, but i'm not sure about that !
I'm reading this documentation to see structures fields :
http://www.opensource.apple.com/source/libpcap/libpcap-18/libpcap/pcap.h
http://www.opensource.apple.com/source/libpcap/libpcap-9/libpcap/pcap-int.h
But again, the apple.com is scaring me, i'm not sure that I should rely on that. For instance, pcap-int.h doesn't seem to exist in my system.
Thank you !
For instance, pcap-int.h doesn't seem to exist in my system.
It's not supposed to. It's part of the pcap source code, but it's internal to libpcap, and the data structures it defines are subject to change from cap release to release, so you can't use them in a pcap program.
You rarely if ever need to the file descriptor associated with a pcap_t, but, in those rare cases where you do, you get it with the pcap_fileno() function:
printf("fd=%d\n", pcap_fileno(result));
However, when you open a capture file, using pcap_open_offline(), rather than opening a device for a live capture, there is no file descriptor associated with it, there's just a "standard I/O" FILE *. As the man page for pcap_fileno() says:
If p refers to a ``savefile'' that was opened using functions such as
pcap_open_offline() or pcap_fopen_offline(), a ``dead'' pcap_t opened
using pcap_open_dead(), or a pcap_t that was created with pcap_create()
but that has not yet been activated with pcap_activate(), it returns
-1.
so it should print "fd=-1" in your program.
The first answer is saying "The error is because the compiler cannot see the definition of the structure" but in my case the structure is pcap_t and is typedef in pcap.h, which i included.
It's typedefed as a structure in pcap.h, but that structure isn't fully defined in pcap.h. C allows a pointer to a structure that's not fully defined; this allows a library to provide a "handle" for a data structure that only the library itself can look at or modify. That's the case with the pcap_t structure; code outside libpcap should not look at it or modify it, it should make calls to libpcap routines to do that.
Also, I'm on Ubuntu, and i cannot find all my .h file about cap.
You probably need to install the "libpcap-dev" package. The "libpcap" package just installs enough libraries to allow programs already compiled with libpcap to run; the "libpcap-dev" package installs the header files to allow programs to be compiled with libpcap.
When I look on google, I only find .h from apple and windows
It doesn't find the GitHub repository for libpcap? That's surprising.
so I assume that i'm using the same as the apple one
Apple's libpcap is based on the one from the Tcpdump Group, which is the one on GitHub. The one in Ubuntu is also based on the one from the Tcpdump Group, as is WinPcap, which is the version for Windows.

undefined reference to `__kmalloc'

While compiling code that uses the SCTP kernel header <sctp/chunk.h>I got a puzzling compiler error(with blue text instead of read) that was trigged by the calling of the kmalloc function whose prototype is defined in <linux/slob-def.h>. Here is the function that caused it:
/* Allocate and initialize datamsg. */
SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp)
{
struct sctp_datamsg *msg;
msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
if (msg) {
sctp_datamsg_init(msg);
SCTP_DBG_OBJCNT_INC(datamsg);
}
return msg;
}
The gcc error message(compiling in native C):
/tmp/ccKDKVjf.o: In function `sctp_datamsg_new':
s.c:(.text+0x2215): undefined reference to `__kmalloc'
collect2: error: ld returned 1 exit status
So what I'm wondering is if the kmalloc function source code properly defined(or not actually implemented at all, or if code that calls this function can only be compiled in kernel mode. I was not actually trying to build an output file(yet), the compile command I issued in Emacs was: gcc s.c (where s.c is the .c file that contains the <sctp/chunk.h> header — just trying to make sure everything compiles properly before building an output file).
That's a linker error, the code compiled fine. Next time, specify -c to avoid linking.
If you are trying to build kernel source without including kernel headers and linking against other kernel modules and the kernel itself, you are going to get errors.
You cannot just use gcc to build kernel source code. There is a way to build them.

Typedefs included, but not functions

I'm writing some code that uses a C library provided by MATLAB (to extract data from *.mat files). In my IDE (Code::Blocks), I've included the folder containing the necessary "mat.h", which is on a network drive. My code recognises types defined in mat.h when I do this, but whenever I call functions from the file I get an "undefined reference" error. This is the same case for the example code MathWorks provides. What sort of problem usually causes this?
#include "mat.h"
int main (void) {
MATFile *pmat; // Compiles only when compiler is told to search in mat.h directory
pmat = matOpen("example_filename", "r"); // Never compiles
return 0;
}
Thanks!
Cameron
"undefined reference" is normally a linker error. It's not a problem of a header file. You need to tell the linker to link MATLAB's library (or a dedicated object) to your program.
No idea how this is done in Code::Blocks though. In the Code:Blocks documentation it is described here.
Have you checked the contents of mat.h? Does it declare matOpen()? Also, does the error occur when compiling or linking? If it's during the link phase, you probably need to reference the library that contains the implementation of matOpen() (a .lib in Windows, or .a in Unix). The .h file only declares the function.

Resources