New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File common/include/byteswap.h clashes with built-in toolchain definition files #5
Comments
What is your build environment? |
It's an uClibc based toolchain for mips32r2 built using buildroot, used for building binaries for the GCW-Zero console. You can find the toolchain and more info here: |
Thanks for the info, I'll check into it quick. The compiler and paths threw me off, I haven't seen this before. Can you try to compile the following and paste me any output (if failure)? #include <stdint.h>
static uint32_t some_func( const uint32_t& ) { /* No-op */ }
static int32_t some_func( const int32_t& ) { /* No-op */ }
int main()
{
return 0;
} You should be able to compile it with |
Build works as intended, it's definately not a problem in the toolchain. Compiling the header as a separate thing works too. |
This is valid by the C++ spec. I'll let @vLKp weigh in on this, though. |
There is a system header named "/usr/include/byteswap.h" in both glibc and uClibc, which "/usr/include/endian.h" tries to include, but it gets "common/include/byteswap.h" instead because it comes first in the include search path. I don't know if this causes the problem Johnny reported, but it would be a good precaution in any case to rename "common/include/byteswap.h" to avoid this name clash. Intercepting system header includes can only lead to trouble. I agree the code is valid. It also builds fine with the GCW Zero toolchain if built in isolation, so there seems to be a strange interaction between the toolchain and the DXX build that breaks things. I'm one of the maintainers of the GCW Zero toolchain, by the way. |
This is strange - as it builds on my systems fine. Perhaps there is some inclusion ordering issue. I will review it shortly, and possibly rename |
@JohnnyonFlame Try it now, let me know if it works. Also, forgive that few minutes where I broke everything because I forgot what branch I was on and merged. Whoops. 👍 |
No biggie. The commit fixes the problem, thanks for your time. |
This was never intended to intercept system headers, and doing so is work fixing. However, I think the originally reported failure shows a problem in the endian header: the Rebirth header works fine when compiled as C++, but not when compiled as C. Though the compiler was invoked in C++ mode, it appears that endian.h included byteswap.h while inside an extern "C" block, thereby switching to C-style parsing. Generally, you should not have a language mode override open when you include other headers. The included headers may only work with the default parse language. I can reproduce the reported error if I wrap byteswap.h inside an extern "C" block. Due to limited interaction with the preprocessor, wrapping the header in _#ifdef _cplusplus does not help, since the preprocessor definitions remain set to C++. The only ways to get the right results are either to wrap every C++ header in an explicit extern "C++" to reset the language mode or to assume the caller left the language mode on a sane default. |
Ah, the error message indeed says "declaration of C function". That explains it: in C there is no name mangling of symbols to support overloading. Thanks for solving the mystery :) The extern "C" is inserted by the __BEGIN_DECLS macro, defined in |
Only respawn when the player presses a fire key/button (primary, secondary, or flare). Only clear primary, second, flare, and bomb when respawning. This allows dead players to use the automap or change their camera views. This is a necessary step to flushing only the firing inputs on respawn, as requested by Mako88 in <#104>. Currently, inputs are flushed again by the activation of the game window, so respawn still flushes all inputs. #1 0x00005555555cee19 in game_flush_inputs () at similar/main/game.cpp:374 #2 game_handler (event=...) at similar/main/game.cpp:1114 #3 0x0000555555576113 in window_send_event (wind=..., event=...) at common/arch/sdl/window.cpp:208 #4 0x000055555557627b in WINDOW_SEND_EVENT (file=0x5555556dc126 "common/arch/sdl/window.cpp", e=0x5555556dc141 "EVENT_WINDOW_ACTIVATED", line=179, event=..., w=...) at common/include/window.h:111 #5 window_set_visible (w=..., visible=visible@entry=1) at common/arch/sdl/window.cpp:179 #6 0x00005555555e90f5 in window_set_visible (visible=1, wind=<optimized out>) at common/include/window.h:90 #7 DoPlayerDead () at similar/main/gameseq.cpp:1479 #8 0x000055555563ed65 in dead_player_frame () at similar/main/object.cpp:1486 #9 0x00005555555cf4df in GameProcessFrame () at similar/main/game.cpp:1329 #10 game_handler (event=...) at similar/main/game.cpp:1157
Returning from a secret level clears the player's `hostages_on_board` to 0 as part of initializing a "new" ship, but this is not desirable behavior. Copy the counter out before and back afterward. ``` Thread 1 "d2x-rebirth-edi" hit Hardware watchpoint 1: -location d2x::LevelUniqueObjectState.Objects._M_elems[0].ctype.player_info.mission.hostages_on_board Old value = 5 '\005' New value = 0 '\000' #0 d2x::init_player_stats_ship (GameTime64=<optimized out>, plrobj=...) at similar/main/gameseq.cpp:613 #1 d2x::init_player_stats_level (secret_flag=d2x::secret_restore::survived, plrobj=..., plr=...) at similar/main/gameseq.cpp:615 #2 d2x::StartNewLevelSub (level_num=level_num@entry=3, page_in_textures=page_in_textures@entry=1, secret_flag=secret_flag@entry=d2x::secret_restore::survived) at similar/main/gameseq.cpp:1901 #3 d2x::state_restore_all_sub (LevelSharedDestructibleLightState=..., secret=d2x::secret_restore::survived, filename=<optimized out>) at similar/main/state.cpp:1670 #4 d2x::state_restore_all (in_game=in_game@entry=1, secret=secret@entry=d2x::secret_restore::survived, filename_override=<optimized out>, blind=blind@entry=dcx::blind_save::no) at similar/main/state.cpp:1490 #5 d2x::ExitSecretLevel () ``` Reported-by: teratorn <#495>
I got this in Fight For Your Life, level 19: main/wall.c:314(wall_open_door): Assert(w->type == WALL_DOOR) ================================================================= ==3862770==ERROR: AddressSanitizer: global-buffer-overflow on address 0x562dee57e448 at pc 0x562decd2169c bp 0x7ffc5d624400 sp 0x7ffc5d6243f8 READ of size 2 at 0x562dee57e448 thread T0 #0 0x562decd2169b in find_connect_side main/gameseg.c:85 dxx-rebirth#1 0x562ded061683 in wall_open_door main/wall.c:367 dxx-rebirth#2 0x562decc10ccf in collide_robot_and_wall main/collide.c:115 dxx-rebirth#3 0x562decc3d5a1 in collide_object_with_wall main/collide.c:2598 dxx-rebirth#4 0x562decfa4ef1 in do_physics_sim main/physics.c:529 dxx-rebirth#5 0x562decf8f1c5 in object_move_one main/object.c:1727 dxx-rebirth#6 0x562decf92000 in object_move_all main/object.c:1858 dxx-rebirth#7 0x562deccc8090 in GameProcessFrame main/game.c:1126 dxx-rebirth#8 0x562deccc5ea9 in game_handler main/game.c:904 dxx-rebirth#9 0x562decb5c486 in window_send_event arch/sdl/window.c:230 dxx-rebirth#10 0x562decb4ed2c in event_process arch/sdl/event.c:184 dxx-rebirth#11 0x562decb4efa2 in window_run_event_loop arch/sdl/event.c:206 dxx-rebirth#12 0x562decdfbe8d in main main/inferno.c:341 dxx-rebirth#13 0x7f7ec936ed09 in __libc_start_main ../csu/libc-start.c:308 (/mnt/big/doh/sandgrube/dxx-rebirth/d2x-rebirth-gl+0x7bcd69) 0x562dee57e448 is located 4 bytes to the right of global variable 'd_tick_step' defined in 'main/mglobal.c:38:5' (0x562dee57e440) of size 4 0x562dee57e448 is located 56 bytes to the left of global variable 'Segments' defined in 'main/mglobal.c:40:9' (0x562dee57e480) of size 10720000 SUMMARY: AddressSanitizer: global-buffer-overflow main/gameseg.c:85 in find_connect_side Shadow bytes around the buggy address: 0x0ac63dca7c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7c70: 00 00 00 00 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 =>0x0ac63dca7c80: 04 f9 f9 f9 f9 f9 f9 f9 04[f9]f9 f9 f9 f9 f9 f9 0x0ac63dca7c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ac63dca7cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==3862770==ABORTING Possibly unreproducable. Judging from collide_robot_and_wall, maybe it's a case where a wall was marked as needing a key, but there's no door? Unknown. Try to avoid this by returning if it makes no sense.
Proper solution would be renaming the aforementioned file.
Here's a partial failed scons log for reference.
http://pastebin.com/ZWKabef4
The text was updated successfully, but these errors were encountered: