I was able to port a program originally written for Linux. After a lot of learning, trial, and error, I replaced all the Linux specific stuff with FreeBSD counterparts. I proceeded to cobble together a Makefile that I'm sure most people would criticize me heavily for. It compiled and linked. Then of course when I went to run it I get a segmentation fault.
Mind you, while I do have a background in C and programming in general, I am by no means an "experienced" C programmer, let a lone a systems programmer. Most of what I know about C, FreeBSD user land programming, Sockets, and IO Multiplexing, is stuff I learned by watching some video courses. To what surmounts to a period of a few weeks. Specifically for the purpose of porting Linux software to FreeBSD.
Anyway...
After some debugging (if that's what you would call sprinkling around sprintf() statements), I track it down to the fclose() system call. I'm confused. Online research points the finger at memory corruption, and the tool to use is devel/valgrind. I've heard about it before, but never had a reason to actually sit down and use it. So I take this opertunity to use it.
It spits this out:
Pretty much giving me information I already knew. Except one thing that I find peculiar:
I am unable to track down where that call is happening. At this point I'm pushing the boundaries of my knowledge. I can only make educated guesses or just brute force things. Is a macro involved?
I search the source code files for the string "_close", and something comes up in a header file:
And the implimentation in a C source file:
I have no clue what purpose this serves, but it does seem suspicious. I suspect this is overriding something somewhere. I rename the function by appending a '1' to it. Everything compiles, and I run the program. It doesn't crash with a segmentation fault.
But why? What did I do, and how was this even working on Linux to begin with?
Mind you, while I do have a background in C and programming in general, I am by no means an "experienced" C programmer, let a lone a systems programmer. Most of what I know about C, FreeBSD user land programming, Sockets, and IO Multiplexing, is stuff I learned by watching some video courses. To what surmounts to a period of a few weeks. Specifically for the purpose of porting Linux software to FreeBSD.
Anyway...
After some debugging (if that's what you would call sprinkling around sprintf() statements), I track it down to the fclose() system call. I'm confused. Online research points the finger at memory corruption, and the tool to use is devel/valgrind. I've heard about it before, but never had a reason to actually sit down and use it. So I take this opertunity to use it.
It spits this out:
Code:
==2629== Invalid read of size 4
==2629== at 0x2BF8C0: _close (in /usr/me/daniel/Documents/SeaTidePool/bin/ckpool)
==2629== by 0x4AA2C37: ??? (in /lib/libc.so.7)
==2629== by 0x4AA2D4C: fclose (in /lib/libc.so.7)
==2629== by 0x2CA244: json_load_file (load.c:1045)
==2629== by 0x2299E7: parse_config (ckpool.c:1442)
==2629== by 0x228419: main (ckpool.c:1747)
==2629== Address 0x4 is not stack'd, malloc'd or (recently) free'd
==2629==
==2629==
==2629== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==2629== Access not within mapped region at address 0x4
==2629== at 0x2BF8C0: _close (in /usr/home/me/Documents/SeaTidePool/bin/ckpool)
==2629== by 0x4AA2C37: ??? (in /lib/libc.so.7)
==2629== by 0x4AA2D4C: fclose (in /lib/libc.so.7)
==2629== by 0x2CA244: json_load_file (load.c:1045)
==2629== by 0x2299E7: parse_config (ckpool.c:1442)
==2629== by 0x228419: main (ckpool.c:1747)
Pretty much giving me information I already knew. Except one thing that I find peculiar:
Code:
at 0x2BF8C0: _close (in /usr/home/me/Documents/SeaTidePool/bin/ckpool)
I am unable to track down where that call is happening. At this point I'm pushing the boundaries of my knowledge. I can only make educated guesses or just brute force things. Is a macro involved?
I search the source code files for the string "_close", and something comes up in a header file:
C:
void _close(int *fd, const char *file, const char *func, const int line);
#define _Close(FD) _close(FD, __FILE__, __func__, __LINE__)
#define Close(FD) _close(&FD, __FILE__, __func__, __LINE__)
And the implimentation in a C source file:
C:
void _close(int *fd, const char *file, const char *func, const int line)
{
int sockd;
if (*fd < 0)
return;
sockd = *fd;
LOGDEBUG("Closing file handle %d", sockd);
*fd = -1;
if (unlikely(close(sockd))) {
LOGWARNING("Close of fd %d failed with errno %d:%s from %s %s:%d",
sockd, errno, strerror(errno), file, func, line);
}
}
I have no clue what purpose this serves, but it does seem suspicious. I suspect this is overriding something somewhere. I rename the function by appending a '1' to it. Everything compiles, and I run the program. It doesn't crash with a segmentation fault.
But why? What did I do, and how was this even working on Linux to begin with?