View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003039 | FSSCP | Build system | public | 2014-05-07 16:25 | 2014-05-22 18:37 |
Reporter | z64555 | Assigned To | |||
Priority | high | Severity | minor | Reproducibility | random |
Status | resolved | Resolution | fixed | ||
Platform | x86_64 | OS | Microsoft Windows | OS Version | 8.1 |
Product Version | 3.7.2 RC1 | ||||
Target Version | 3.7.2 | ||||
Summary | 0003039: Debug Console Commands Sometimes Don't Show Up | ||||
Description | Came across this issue some time ago when initially working with the debug console. Essentially, a number of DCF's defined in the FSO code base are not being added to the command list. If they're not on the command list, then a user cannot see nor use them from the debug console. | ||||
Steps To Reproduce | 1. Run any build post-r10622. 2. Get to the login screen, and press Shift + Enter to bring up the debug console. 3. Enter 'help' into the debug console to bring up the help screen. A list of available commands should be shown. 4. Note the number of available commands. There should be over 100 of them. | ||||
Additional Information | I have a suspicion that this is build related, and that the DCF's are getting optimized out somehow. Another suspicion is that they're just not getting added to the list properly. I may have to consider using a different method of declaring and adding the DCF's. | ||||
Tags | No tags attached. | ||||
|
Issue seems to be related to the tool used to build it. Chief and I have confirmed all/most of the DCFs are properly added for MSVS 2012, and for OSX. VC2008 is confirmed to have the issue, haven't tried VC2010 or VC6 yet. |
|
I am going to try VC6 if the last commit fixed compiling with it. |
|
FYI, on Linux (gcc 4.6.3) the help list starts with "medals" and is only slightly longer than one page so it would seem that not all DCFs are being loaded. However, I can run (for instance) run "cscrew" and get output. Does that mean the problem is only with help, and not loading then DCFs? edit: Oops. Didn't realise you can scroll up with PgUp. If I do that I think I get the complete list. However there may be an issue with the paging? |
|
Yeah I thought the paging was behaving oddly on some platforms too. On OS X I think I got correct paging, and on Windows I think I just got the behavior you got. I may have that reversed though. Edit: Ok yeah, just tested OS X again. At 640x480, the first command is Change...something, and I have the option to see 'More' twice, so it takes 3 pages to show what seems to be everything. The Windows VC2012 build must be the one that didn't paginate for me yesterday. |
|
Just to clarify the paginate issues, could you link a screenshot of what's happening? |
|
I assume that paginating the help results, and not just dumping them all and then requiring you to scroll back up to read them, is the correct behavior? The one I saw misbehaving is at home, I'll try to get screenshots tonight. Maybe even record it. |
|
Original behavior was to dump the help results until it filled up the buffer. Since that seems to be unintuitive, the behavior has been changed to fill up the screen before pausing the output. Note that this behavior is only limited to --help, if other commands wish to do the same then they will have to copy the for loop... or make another accessory function around the for loop and use that. |
|
m3039.patch (7,795 bytes)
From b405c1c84b4119aa7f4e1506802c64d9745cfd68 Mon Sep 17 00:00:00 2001 From: z64555 <z1281110@gmail.com> Date: Tue, 20 May 2014 20:57:13 -0500 Subject: [PATCH] Fixes 3039: C++ stdlib was having data race issues with instanciating the debug_commands and the vector that was supposed to contain them. Seems like :v: ran into this issue a few times before... --- code/debugconsole/console.cpp | 19 +++++----- code/debugconsole/console.h | 5 +++ code/debugconsole/consolecmds.cpp | 79 +++++++++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 29 deletions(-) diff --git a/code/debugconsole/console.cpp b/code/debugconsole/console.cpp index b7eb607..c7acecb 100644 --- a/code/debugconsole/console.cpp +++ b/code/debugconsole/console.cpp @@ -138,8 +138,9 @@ void dc_do_command(SCP_string *cmd_str) * Call the function to process the command (the rest of the command line is in the parser) * Function takes care of long_help and status depending on the mode. */ + int i; SCP_string command; - extern SCP_vector<debug_command*> dc_commands; // z64: I don't like this extern here, at all. Nope nope nope. + extern debug_command* dc_commands[]; // z64: I don't like this extern here, at all. Nope nope nope. if (cmd_str->empty()) { return; @@ -149,15 +150,20 @@ void dc_do_command(SCP_string *cmd_str) dc_stuff_string_white(command); // Grab the first token, presumably this is a command - SCP_vector<debug_command*>::iterator it = std::find_if(dc_commands.begin(), dc_commands.end(), is_dcmd(command.c_str())); + for (i = 0; i < dc_commands_size; ++i) { + + if (stricmp(dc_commands[i]->name, command.c_str()) == 0) { + break; + } // Else, continue + } - if (it == dc_commands.end()) { + if (i == dc_commands_size) { dc_printf("Command not found: '%s'\n", command.c_str()); return; } // Else, we found our command try { - (*it)->func(); // Run the command! + dc_commands[i]->func(); // Run the command! } catch (errParseString err) { dc_printf("Require string(s) not found: \n"); @@ -267,17 +273,12 @@ void dc_draw_window(bool show_prompt) void dc_init(void) { - extern SCP_vector<debug_command*> dc_commands; - if (debug_inited) { return; } debug_inited = TRUE; - // Sort debug_commands - std::sort(dc_commands.begin(), dc_commands.end(), dcmd_less); - // Init window settings dc_font = FONT1; row_height = ((Current_font->h) * 3) / 2; // Row/Line height, in pixels diff --git a/code/debugconsole/console.h b/code/debugconsole/console.h index 867a979..c8abde1 100644 --- a/code/debugconsole/console.h +++ b/code/debugconsole/console.h @@ -22,6 +22,8 @@ #include "globalincs/pstypes.h" #include "globalincs/vmallocator.h" +#define DC_MAX_COMMANDS 300 + class debug_command; /** @@ -222,6 +224,8 @@ public: const char *help; //!< The short help string, as shown by 'help <command>' void (*func)(); //!< Pointer to the function that to run when this command is evoked + debug_command(); + /** * @brief Adds a debug command to the debug_commands map, if it isn't in there already. * @@ -248,6 +252,7 @@ public: }; extern bool Dc_debug_on; +extern int dc_commands_size; extern uint lastline; extern SCP_string dc_command_str; // The rest of the command line, from the end of the last processed arg on. diff --git a/code/debugconsole/consolecmds.cpp b/code/debugconsole/consolecmds.cpp index 8d511b6..46e533a 100644 --- a/code/debugconsole/consolecmds.cpp +++ b/code/debugconsole/consolecmds.cpp @@ -26,8 +26,8 @@ #include <algorithm> // ========================= GLOBALS ========================= -SCP_vector<debug_command*> dc_commands; -typedef SCP_vector<debug_command*>::iterator dc_commands_it; +debug_command *dc_commands[DC_MAX_COMMANDS]; +int dc_commands_size = 0; // ========================= LOCALS ========================== // dcf_shell commands @@ -36,23 +36,53 @@ void dc_shell_resize( void ); void dc_shell_resize_buf( void ); // =================== class debug_command =================== -debug_command::debug_command(const char *_name, const char *_help, void (*_func)()) - : name(_name), help(_help), func(_func) -{ - dc_commands_it it = std::find_if(dc_commands.begin(), dc_commands.end(), is_dcmd(_name)); - - if (it != dc_commands.end()) { - Int3(); // Command already exists! Somebody didn't use the DCF macro as they should've... +debug_command::debug_command() +: name(""), help(""), func(NULL) { +}; + +debug_command::debug_command(const char *_name, const char *_help, void(*_func)()) + : name(_name), help(_help), func(_func) { + int i = 0; + int ret = 0; + + if (dc_commands_size > DC_MAX_COMMANDS) { + Error(LOCATION, "Too many debug console commands! Please inform a coder to increase DC_MAX_COMMANDS."); + return; } - dc_commands.push_back(this); + // Start the insertion sort by finding where to stick the debug command + for (; i < dc_commands_size; ++i) { + ret = stricmp(dc_commands[i]->name, _name); + + if (ret == 0) { + Error(LOCATION, "Debug Command %s already exists! Please inform a coder immediately.", _name); + return; + } else if (ret > 0) { + // Insert the command here + break; + } // Else, do nothing + } + + // Then, do the insertion + if (i < dc_commands_size) { + for (int j = dc_commands_size; j > i; --j) { + dc_commands[j] = dc_commands[j - 1]; + } + dc_commands[i] = this; + dc_commands_size++; + } else { + dc_commands[dc_commands_size] = this; + dc_commands_size++; + } } // ============================== IMPLEMENTATIONS ============================= DCF(debug, "Runs a command in debug mode.") { + int i; SCP_string command = ""; + Dc_debug_on = true; dc_stuff_string_white(command); @@ -62,16 +92,20 @@ DCF(debug, "Runs a command in debug mode.") return; } // Else, command is present. - dc_commands_it it = std::find_if(dc_commands.begin(), dc_commands.end(), is_dcmd(command.c_str())); + for (i = 0; i < dc_commands_size; ++i) { + if (stricmp(dc_commands[i]->name, command.c_str()) == 0) { + break; + } // Else, continue + } - if (it == dc_commands.end()) { + if (i == dc_commands_size) { dc_printf("<debug> Command not found: '%s'\n", command.c_str()); return; - } // Else, command exists. Run it. + } // Else, we found our command dc_printf("<debug> Executing command: '%s'\n", command.c_str()); // try { - (*it)->func(); + dc_commands[i]->func(); // } catch { // } @@ -82,6 +116,7 @@ DCF(help, "Displays the help list." ) { extern uint DROWS; + int i; SCP_string command = ""; dc_maybe_stuff_string_white(command); @@ -92,14 +127,18 @@ DCF(help, "Displays the help list." ) return; } else if (command != "") { - dc_commands_it it = std::find_if(dc_commands.begin(), dc_commands.end(), is_dcmd(command.c_str())); + for (i = 0; i < dc_commands_size; ++i) { + if (stricmp(dc_commands[i]->name, command.c_str()) == 0) { + break; + } // Else, continue + } - if (it == dc_commands.end()) { + if (i == dc_commands_size) { dc_printf("Command not found: '%s'\n", command.c_str()); return; - } + } // Else, we found our command - dc_printf("%s\n", (*it)->help); + dc_printf("%s\n", dc_commands[i]->help); return; } // Else, command line is empty, print out the help list @@ -111,12 +150,12 @@ DCF(help, "Displays the help list." ) dc_printf("\n"); dc_printf(" Available commands:\n"); - for (dc_commands_it it = dc_commands.begin(); it != dc_commands.end(); ++it) { + for (i = 0; i < dc_commands_size; ++i) { if (((lastline % DROWS) == 0) && (lastline != 0)) { dc_pause_output(); } - dc_printf(" %s - %s\n", (*it)->name, (*it)->help); + dc_printf(" %s - %s\n", dc_commands[i]->name, dc_commands[i]->help); } } -- 1.8.3.msysgit.0 |
|
Issue appears to have been more of an issue with stdlib rather than the build system. std::vector might've gotten an update sometime between VS2008 and 2010, hence why the issue was only showing up on VS2008 and VC6. I've attached a patch which reverts to the old method of using an array instead of one of the dynamic containers, since it works so well. |
|
The patch fixes the issue I had on Centos 6 with gcc 4.4.7 |
|
Yeah, seems to fix VC2008 too. Go ahead and commit whenever, unless we're waiting on any other code review. |
|
Fix committed to trunk@10712. |
fs2open: trunk r10712 2014-05-22 13:51 Ported: N/A Details Diff |
Fixes 3039: C++ STL was having data race issues with instantiating the debug_commands and the vector that was supposed to reference them. Seems like :v: ran into this issue a few times before... |
Affected Issues 0003039 |
|
mod - /trunk/fs2_open/code/debugconsole/console.cpp | Diff File | ||
mod - /trunk/fs2_open/code/debugconsole/console.h | Diff File | ||
mod - /trunk/fs2_open/code/debugconsole/consolecmds.cpp | Diff File |
Date Modified | Username | Field | Change |
---|---|---|---|
2014-05-07 16:25 | z64555 | New Issue | |
2014-05-07 16:25 | z64555 | Status | new => assigned |
2014-05-07 16:25 | z64555 | Assigned To | => chief1983 |
2014-05-07 18:27 | z64555 | Note Added: 0015724 | |
2014-05-07 19:12 | chief1983 | Note Added: 0015725 | |
2014-05-08 10:39 | niffiwan | Note Added: 0015726 | |
2014-05-08 12:39 | niffiwan | Note Edited: 0015726 | |
2014-05-08 15:16 | chief1983 | Note Added: 0015727 | |
2014-05-08 16:32 | chief1983 | Note Edited: 0015727 | |
2014-05-08 20:11 | z64555 | Note Added: 0015729 | |
2014-05-08 20:39 | chief1983 | Note Added: 0015730 | |
2014-05-09 11:10 | z64555 | Note Added: 0015733 | |
2014-05-21 01:50 | z64555 | File Added: m3039.patch | |
2014-05-21 01:52 | z64555 | Note Added: 0015753 | |
2014-05-21 01:53 | z64555 | Assigned To | chief1983 => |
2014-05-21 01:53 | z64555 | Status | assigned => code review |
2014-05-21 21:05 | niffiwan | Note Added: 0015754 | |
2014-05-22 15:47 | chief1983 | Note Added: 0015755 | |
2014-05-22 15:47 | chief1983 | Note Edited: 0015755 | |
2014-05-22 18:37 | z64555 | Changeset attached | => fs2open trunk r10712 |
2014-05-22 18:37 | z64555 | Note Added: 0015756 | |
2014-05-22 18:37 | z64555 | Status | code review => resolved |
2014-05-22 18:37 | z64555 | Resolution | open => fixed |