5

I have a project that needs to build on Windows, Linux, and VxWorks. The project is built on Linux and Windows but cross compiled for VxWorks. To handle endianness across multiple platforms, it uses ntoh.h. The Linux machine is little endian but ntohl doesn't swap in my program.

I wrote a test program that directly includes in.h. That swaps appropriately. I wrote another test program that just includes the ntoh.h. That swaps appropriately. Both test programs link to lib64/libc.so.6.

However, when I compile my project, ntohl doesn't swap. I can't break on ntohl using gdb "break ntohl" command. When building, I see LITTLE ENDIAN warning (see below) and do not see the "SHOULDNT BE HERE" error.

Please help. I don't understand why this problem is occurring.

Below is ntoh.h:

#ifndef __ntoh__
#define __ntoh__

#include "basic_types.h"

#ifdef WIN32
    #include <winsock2.h>
#elif LINUX
    #include <netinet/in.h>

    //This is here to determine what __BYTE_ORDER is set to in netinet/in.h.
    // Not in original code 
    #if __BYTE_ORDER == __BIG_ENDIAN
    #warning BIG ENDIAN BYTE ORDER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #endif 

    //This is here to determine what __BYTE_ORDER is set to in netinet/in.h. 
    // Not in original code
    #if __BYTE_ORDER == __LITTLE_ENDIAN
    #warning YAY LITTLE ENDIAN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #endif 
#else

  #error SHOULDNT BE HERE     //added for debugging purposes
  #define ntohl(x)        (x)
  #define ntohs(x)        (x)
  #define htonl(x)        (x)
  #define htons(x)        (x)

#endif

#endif // __ntoh__

Part of my compile command:

g++ -DDAU_PARSER -DNO_MT -DTEST_CLOCK -DLINUX  -g -Irelease/include -Irelease/include/Record_Data/ -Irelease/include/Utility -o dauParser DAU_Support_Tools/src/dau_parser.cpp DAU_Support_Tools/src/dau_parser_write_data_to_file.cpp Utility/src/Messaging/Communications/Message.cpp Utility/src/time_type.cpp Utility/src/collectable.cpp Utility/src/clist.cpp Utility/src/clock.cpp Utility/src/test_clock.cpp Utility/src/mutex.cpp Utility/src/ntoh.cpp ... 

The error is generated by the following lines:

int deadbeef = 0xDEADBEEF; 
printf("TESTING DEADBEEF %x %x\n", deadbeef, ntohl(deadbeef) ); 

The output from those two lines produce same output. TESTING DEADBEEF deadbeef deadbeef

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
Kat
  • 447
  • 2
  • 7
  • 21
  • 2
    Please add the code that actually doesn't work correctly. – wRAR Feb 25 '13 at 21:55
  • 1
    From your edit, how is it possible that `printf("%x", 0xdeadbeef)` produces `efbeadde`? You might want to post a minimal example showing your real code. – Austin Phillips Feb 25 '13 at 22:18
  • @AustinPhillips: Sorry, you're right. Description of output was fixed. – Kat Feb 25 '13 at 22:23
  • 2
    Are you cross-compiling? If not, which platform are you building on, and which executable fails? – Michael Foukarakis Feb 25 '13 at 22:23
  • Just checking... You do understand that `nohl` will be a no-op on big endian architectures right? And some architectures such as later ARMs are bi-endian. – Austin Phillips Feb 25 '13 at 22:26
  • @MichaelFoukarakis: I am. The endian is handle correctly for VxWorks and Windows but fails for Linux. I was successful read a saved file from a VxWorks machine (Big Endian) on a Window Platform (Little Endian). The Windows platform has the same processor & endianness as the Linux machine. I'm using the same file for the Linux compilation but it fails to read it properly. – Kat Feb 25 '13 at 22:28
  • @AustinPhillips: Yes, I know how nohl works. The Linux machine I'm working on is Little Endian architecture. The file is being saved on a machine with Big Endian architecture. I have a Windows compilation that can read the saved file & handle the Endian appropriately - on a machine with the same processor. – Kat Feb 25 '13 at 22:31
  • I'm not entirely sure `#elif LINUX` is correct. You may need to switch to `#if defined()` forms... Documentation seems to vary on this - `#elif` definitely supports an argument in `#if` clauses, but maybe not in `#ifdef`... Don't have a copy of the standard handy to check at the moment. – twalberg Feb 25 '13 at 22:42
  • @twalberg: Already tried both ways **#elif Linux** and **#if defined** and both produce the same results. – Kat Feb 25 '13 at 22:48
  • 1
    Don't use double underscores in your identifiers - those are reserved for the compiler. See http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – Mark Ransom Feb 25 '13 at 22:51
  • @MarkRansom: That's only there so I can identify what is __BYTE_ORDER is set to. __BYTE_ORDER, __BIG_ENDIAN, and __LITTLE_ENDIAN is used in netinet/in.h. I plan on removing that once I get my code compiling correctly. – Kat Feb 25 '13 at 23:11
  • @Kat I was referring to `__ntoh__` actually. – Mark Ransom Feb 25 '13 at 23:41

1 Answers1

6

The output from those two lines produce same output. TESTING DEADBEEF deadbeef deadbeef

Well, something is wrong, but we can't tell you what. You have to debug this problem, as you are the only one who can observe it.

Start with the simplest possible example:

cat t.c; gcc t.c && ./a.out
#include <netinet/in.h>
#include <stdio.h>

int main() {
  int deadbeef = 0xDEADBEEF; 
  printf("TESTING DEADBEEF %x %x\n", deadbeef, ntohl(deadbeef));
  return 0;
}


TESTING DEADBEEF deadbeef efbeadde

Did this produce expected result?

  • No: your toolchain and headers are busted.
  • Yes: your toolchain is ok, but your actual code does something different from the example.
    Run your code through preprocessor: gcc -dD -E -DLINUX ntoh.cpp, and look at what the ntohl macro expands to, and where it's coming from.

My guess is that you have something stupid in one of your headers, e.g.

#undef ntohl
#define ntohl(x) (x)
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • These flags are just what I needed. My software was calling a stale ntoh.h file that did not include the **error SHOULD NOT BE HERE** and the **LINUX** definition check. Stale file was defining ntohl(x) as (x)! I updated my makefile to clean correctly. Stale file has been removed. – Kat Feb 26 '13 at 15:36