summaryrefslogtreecommitdiff
path: root/gdbsupport
Commit message (Collapse)AuthorAgeFilesLines
* gdb: Fix building with latest libc++Manoj Gupta2023-04-292-2/+5
| | | | | | | | | | | | | | | | Latest libc++[1] causes transitive include to <locale> when <mutex> or <thread> header is included. This causes gdb to not build[2] since <locale> defines isupper/islower etc. functions that are explicitly macroed-out in safe-ctype.h to prevent their use. Use the suggestion from libc++ to include <locale> internally when building in C++ mode to avoid build errors. Use safe-gdb-ctype.h as the include instead of "safe-ctype.h" to keep this isolated to gdb since rest of binutils does not seem to use much C++. [1]: https://reviews.llvm.org/D144331 [2]: https://issuetracker.google.com/issues/277967395
* gdb: move displaced_step_dump_bytes into gdbsupport (and rename)Andrew Burgess2023-03-293-0/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | It was pointed out during review of another patch that the function displaced_step_dump_bytes really isn't specific to displaced stepping, and should really get a more generic name and move into gdbsupport/. This commit does just that. The function is renamed to bytes_to_string and is moved into gdbsupport/common-utils.{cc,h}. The function implementation doesn't really change. Much... ... I have updated the function to take an array view, which makes it slightly easier to call in a couple of places where we already have a gdb::bytes_vector. I've then added an inline wrapper to convert a raw pointer and length into an array view, which is used in places where we don't easily have a gdb::bytes_vector (or similar). Updated all users of displaced_step_dump_bytes. There should be no user visible changes after this commit. Finally, I ended up having to add an include of gdb_assert.h into array-view.h. When I include array-view.h into common-utils.h I ran into build problems because array-view.h calls gdb_assert. Approved-By: Simon Marchi <simon.marchi@efficios.com>
* gdb, gdbserver, gdbsupport: fix whitespace issuesSimon Marchi2023-03-095-19/+15
| | | | | | Replace spaces with tabs in a bunch of places. Change-Id: If0f87180f1d13028dc178e5a8af7882a067868b0
* gdbsupport: ignore -Wenum-constexpr-conversion in enum-flags.hSimon Marchi2023-03-061-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When building with clang 16, we get: CXX gdb.o In file included from /home/smarchi/src/binutils-gdb/gdb/gdb.c:19: In file included from /home/smarchi/src/binutils-gdb/gdb/defs.h:65: /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/enum-flags.h:95:52: error: integer value -1 is outside the valid range of values [0, 15] for this enumeration type [-Wenum-constexpr-conversion] integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type ^ The error message does not make it clear in the context of which enum flag this fails (i.e. what is T in this context), but it doesn't really matter, we have similar warning/errors for many of them, if we let the build go through. clang is right that the value -1 is invalid for the enum type we cast -1 to. However, we do need this expression in order to select an integer type with the appropriate signedness. That is, with the same signedness as the underlying type of the enum. I first wondered if that was really needed, if we couldn't use std::underlying_type for that. It turns out that the comment just above says: /* Note that std::underlying_type<enum_type> is not what we want here, since that returns unsigned int even when the enum decays to signed int. */ I was surprised, because std::is_signed<std::underlying_type<enum_type>> returns the right thing. So I tried replacing all this with std::underlying_type, see if that would work. Doing so causes some build failures in unittests/enum-flags-selftests.c: CXX unittests/enum-flags-selftests.o /home/smarchi/src/binutils-gdb/gdb/unittests/enum-flags-selftests.c:254:1: error: static assertion failed due to requirement 'gdb::is_same<selftests::enum_flags_tests::check_valid_expr254::archetype<enum_flags<s elftests::enum_flags_tests::RE>, selftests::enum_flags_tests::RE, enum_flags<selftests::enum_flags_tests::RE2>, selftests::enum_flags_tests::RE2, enum_flags<selftests::enum_flags_tests::URE>, selftests::enum_fla gs_tests::URE, int>, selftests::enum_flags_tests::check_valid_expr254::archetype<enum_flags<selftests::enum_flags_tests::RE>, selftests::enum_flags_tests::RE, enum_flags<selftests::enum_flags_tests::RE2>, selfte sts::enum_flags_tests::RE2, enum_flags<selftests::enum_flags_tests::URE>, selftests::enum_flags_tests::URE, unsigned int>>::value == true': CHECK_VALID (true, int, true ? EF () : EF2 ()) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/smarchi/src/binutils-gdb/gdb/unittests/enum-flags-selftests.c:91:3: note: expanded from macro 'CHECK_VALID' CHECK_VALID_EXPR_6 (EF, RE, EF2, RE2, UEF, URE, VALID, EXPR_TYPE, EXPR) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/valid-expr.h:105:3: note: expanded from macro 'CHECK_VALID_EXPR_6' CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/valid-expr.h:66:3: note: expanded from macro 'CHECK_VALID_EXPR_INT' static_assert (gdb::is_detected_exact<archetype<TYPES, EXPR_TYPE>, \ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is a bit hard to decode, but basically enumerations have the following funny property that they decay into a signed int, even if their implicit underlying type is unsigned. This code: enum A {}; enum B {}; int main() { std::cout << std::is_signed<std::underlying_type<A>::type>::value << std::endl; std::cout << std::is_signed<std::underlying_type<B>::type>::value << std::endl; auto result = true ? A() : B(); std::cout << std::is_signed<decltype(result)>::value << std::endl; } produces: 0 0 1 So, the "CHECK_VALID" above checks that this property works for enum flags the same way as it would if you were using their underlying enum types. And somehow, changing integer_for_size to use std::underlying_type breaks that. Since the current code does what we want, and I don't see any way of doing it differently, ignore -Wenum-constexpr-conversion around it. Change-Id: Ibc82ae7bbdb812102ae3f1dd099fc859dc6f3cc2
* Introduce gdb_exception_forced_quitKevin Buettner2023-02-272-1/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit adds a new exception 'gdb_exception_forced_quit', reason code 'REASON_FORCED_QUIT', return mask 'RETURN_MASK_FORCED_QUIT', and a wrapper for throwing the exception, throw_forced_quit(). The addition of this exception plus supporting code will allow us to recognize that a SIGTERM has been received by GDB and then propagate recognition of that fact to the upper levels of GDB where it can be correctly handled. At the moment, when GDB receives a SIGTERM, it will attempt to exit via a series of calls from the QUIT checking code. However, before it can exit, it must do various cleanups, such as killing or detaching all inferiors. Should these cleanups be attempted while GDB is executing very low level code, such as reading target memory from within ps_xfer_memory(), it can happen that some of GDB's state is out of sync with regard to the cleanup code's expectations. In the case just mentioned, it's been observed that inferior_ptid and the current_thread_ are not in sync; this triggers an assert / internal error. This commit only introduces the exception plus supporting machinery; changes which use this new exception are in later commits in this series. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761 Tested-by: Tom de Vries <tdevries@suse.de> Approved-by: Pedro Alves <pedro@palves.net>
* Remove struct bufferTom Tromey2023-02-244-250/+1
| | | | | | | | | | I've long wanted to remove 'struct buffer', and thanks to Simon's earlier patch, I was finally able to do so. My feeling has been that gdb already has several decent structures available for growing strings: std::string of course, but also obstack and even objalloc from BFD and dyn-string from libiberty. The previous patches in this series removed all the uses of struct buffer, so this one can remove the code and the remaining #includes.
* Do not cast away const in agent_run_commandTom Tromey2023-02-142-7/+9
| | | | | | | | | | | | | | | | While investigating something else, I noticed some weird code in agent_run_command (use of memcpy rather than strcpy). Then I noticed that 'cmd' is used as both an in and out parameter, despite being const. Casting away const like this is bad. This patch removes the const and fixes the memcpy. I also added a static assert to assure myself that the code in gdbserver is correct -- gdbserver is passing its own buffer directly to agent_run_command. Reviewed-By: Andrew Burgess <aburgess@redhat.com>
* Move implementation of perror_with_name to gdbsupportAaron Merey2023-02-102-3/+34
| | | | | | | | | | | | | | | | | gdbsupport/errors.h declares perror_with_name and leaves the implementation to the clients. However gdb and gdbserver's implementations are essentially the same, resulting in unnecessary code duplication. Fix this by implementing perror_with_name in gdbsupport. Add an optional parameter for specifying the errno used to generate the error message. Also move the implementation of perror_string to gdbsupport since perror_with_name requires it. Approved-By: Tom Tromey <tom@tromey.com>
* GDB: Switch to using C++ standard integer type limitsMaciej W. Rozycki2023-02-101-1/+7
| | | | | | | | Use <climits> instead of <limits.h> and ditch local fallback definitions for minimum and maximum value macros provided by C++11. Add LONGEST_MAX and LONGEST_MIN definitions. Approved-By: Tom Tromey <tom@tromey.com>
* Let user C-c when waiting for DWARF index finalizationTom Tromey2023-02-091-0/+27
| | | | | | | | | | | | | | | | In PR gdb/29854, Simon pointed out that it would be good to be able to use C-c when the DWARF cooked index is waiting for finalization. The idea here is to be able to interrupt a command like "break" -- not to stop the finalization process itself, which runs in a worker thread. This patch implements this idea, by changing the index wait functions to, by default, allow a quit. Polling is done, because there doesn't seem to be a better way to interrupt a wait on a std::future. For v2, I realized that the thread compatibility code in thread-pool.h also needed an update. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29854
* gdbsupport: add type definitions for pid, lwp and tidSimon Marchi2023-02-021-7/+11
| | | | | | | | | | | | | | A following patch will want to declare variables of the same type as some ptid_t components. To make that easy (and avoid harcoding those types everywhere), define some type definitions in the ptid_t struct for each of them. Use them throughout ptid.h. I initially used pid_t, lwp_t and tid_t, but there is the risk of some system defining the pid_t type using a macro instead of a typedef, which would break things. So, use the _type suffix instead. Change-Id: I820b0bea9dafcb4914f1c9ba4bb96b5c666c8dec Approved-By: Andrew Burgess <aburgess@redhat.com>
* gdbsupport: allow passing nullptr to checked_static_castSimon Marchi2023-01-311-0/+3
| | | | | | | | | | | | | | Both static_cast and dynamic_cast handle nullptr (they return nullptr), so I think checked_static_cast should too. This will allow doing a null check after a checked_static_cast: cooked_index_vector *table = (gdb::checked_static_cast<cooked_index_vector *> (per_bfd->index_table.get ())); if (table != nullptr) return; Change-Id: If5c3134e63696f8e417c87b5f3901240c9f7ea97
* enum_flags to_stringPedro Alves2023-01-301-0/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit introduces shared infrastructure that can be used to implement enum_flags -> to_string functions. With this, if we want to support converting a given enum_flags specialization to string, we just need to implement a function that provides the enumerator->string mapping, like so: enum some_flag { SOME_FLAG1 = 1 << 0, SOME_FLAG2 = 1 << 1, SOME_FLAG3 = 1 << 2, }; DEF_ENUM_FLAGS_TYPE (some_flag, some_flags); static std::string to_string (some_flags flags) { static constexpr some_flags::string_mapping mapping[] = { MAP_ENUM_FLAG (SOME_FLAG1), MAP_ENUM_FLAG (SOME_FLAG2), MAP_ENUM_FLAG (SOME_FLAG3), }; return flags.to_string (mapping); } .. and then to_string(SOME_FLAG2 | SOME_FLAG3) produces a string like "0x6 [SOME_FLAG2 SOME_FLAG3]". If we happen to forget to update the mapping array when we introduce a new enumerator, then the string representation will pretty-print the flags it knows about, and then the leftover flags in hex (one single number). For example, if we had missed mapping SOME_FLAG2 above, we'd end up with: to_string(SOME_FLAG2 | SOME_FLAG3) => "0x6 [SOME_FLAG2 0x4]"); Other than in the unit tests included, no actual usage of the functionality is added in this commit. Approved-By: Simon Marchi <simon.marchi@efficios.com> Change-Id: I835de43c33d13bc0c95132f42c3f97318b875779
* Avoid submitting empty tasks in parallel_for_eachTom Tromey2023-01-171-0/+30
| | | | | | | | | | | | I found that parallel_for_each would submit empty tasks to the thread pool. For example, this can happen if the number of tasks is smaller than the number of available threads. In the DWARF reader, this resulted in the cooked index containing empty sub-indices. This patch arranges to instead shrink the result vector and process the trailing entries in the calling thread.
* Set _WIN32_WINNT in common.m4 configure checkTom Tromey2023-01-113-3/+26
| | | | | | | | | | | | | | | | | | | | | | | GCC recently added support for the Windows thread model, enabling libstdc++ to support Windows natively. However, this supporrt requires a version of Windows later than the minimum version that is supported by GDB. PR build/29966 points out that the GDB configure test for std::thread does not work in this situation, because _WIN32_WINNT is not defined in test program, and so <thread> seems to be fine. This patch is an attempt to fix the problem, by using the same setting for _WIN32_WINNT at configure time as is used at build time. I don't have access to one of the older systems so I don't think I can truly test this. I did do a mingw cross build, though. I'm going to ask the bug reporter to test it. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29966
* gdbsupport: fix scoped_debug_start_end's move constructorSimon Marchi2023-01-051-1/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I spotted a problem with scoped_debug_start_end's move constructor. When constructing a scoped_debug_start_end through it, it doesn't disable the moved-from object, meaning there are now two objects that will do the side-effects of decrementing the debug_print_depth global and printing the "end" message. Decrementing the debug_print_depth global twice is actually problematic, because the increments and decrements get out of sync, meaning we should hit this assertion, in theory: gdb_assert (debug_print_depth > 0); However, in practice, we don't see that. This is because despite the move constructor being required for this to compile: template<typename PT> static inline scoped_debug_start_end<PT &> ATTRIBUTE_NULL_PRINTF (6, 7) make_scoped_debug_start_end (PT &&pred, const char *module, const char *func, const char *start_prefix, const char *end_prefix, const char *fmt, ...) { va_list args; va_start (args, fmt); auto res = scoped_debug_start_end<PT &> (pred, module, func, start_prefix, end_prefix, fmt, args); va_end (args); return res; } ... it is never actually called, because compilers elide the move constructors all the way (the scoped_debug_start_end gets constructed directly in the instance of the top-level caller). To confirm this, I built GDB with -fno-elide-constructors, and now I see it: /home/simark/src/binutils-gdb/gdb/../gdbsupport/common-debug.h:147: internal-error: ~scoped_debug_start_end: Assertion `debug_print_depth > 0' failed. #9 0x00005614ba5f17c3 in internal_error_loc (file=0x5614b8749960 "/home/simark/src/binutils-gdb/gdb/../gdbsupport/common-debug.h", line=147, fmt=0x5614b8733fa0 "%s: Assertion `%s' failed.") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:58 #10 0x00005614b8e1b2e5 in scoped_debug_start_end<bool&>::~scoped_debug_start_end (this=0x7ffc6c5e7b40, __in_chrg=<optimized out>) at /home/simark/src/binutils-gdb/gdb/../gdbsupport/common-debug.h:147 #11 0x00005614b96dbe34 in make_scoped_debug_start_end<bool&> (pred=@0x5614baad7200: true, module=0x5614b891d840 "infrun", func=0x5614b891d800 "infrun_debug_show_threads", start_prefix=0x5614b891d7c0 "enter", end_prefix=0x5614b891d780 "exit", fmt=0x0) at /home/simark/src/binutils-gdb/gdb/../gdbsupport/common-debug.h:235 Fix this by adding an m_disabled field to scoped_debug_start_end, and setting it in the move constructor. Change-Id: Ie5213269c584837f751d2d11de831f45ae4a899f
* gdbsupport: add gdb::string_view_hashSimon Marchi2023-01-051-0/+17
| | | | | | | | | | Add the string_view_hash type, which will be useful to be able to use gdb::string_view as std::unordered_map keys. Use it in gdb/symtab.c, to exercise it. Change-Id: Id69a466ab19a9f6620b5df8a2dd29b5cddd94c00 Approved-By: Andrew Burgess <aburgess@redhat.com>
* gdbsupport: move fast_hash to gdbsupport/common-utils.hSimon Marchi2023-01-051-0/+21
| | | | | | | | The following patch adds a hash type for gdb::string_view in gdbsupport, which will use the fast_hash function. Move the latter to gdbsupport. Change-Id: Id74510e17801e775bd5ffa5f443713d79adf14ad Approved-By: Andrew Burgess <aburgess@redhat.com>
* gdbsupport: move libxxhash configure check to gdbsupportSimon Marchi2023-01-054-0/+544
| | | | | | | | | The following patch moves the fast_hash function, which uses libxxhash, to gdbsupport. Move the libxxhash configure check to gdbsupport (and transitively to gdbserver). Change-Id: I242499e50c8cd6fe9f51e6e92dc53a1b3daaa96e Approved-By: Andrew Burgess <aburgess@redhat.com>
* Update copyright year range in header of all files managed by GDBJoel Brobecker2023-01-01151-151/+151
| | | | | | | This commit is the result of running the gdb/copyright.py script, which automated the update of the copyright year range for all source files managed by the GDB project to be updated to include year 2023.
* gdbsupport: add string_xml_appendfSimon Marchi2022-12-162-0/+115
| | | | | | | | | | | | | | | | | | Add a version of buffer_xml_printf (defined in gdbsupport/buffer.{c,h}) that appends to an std::string, rather than a struct buffer. Call it "string" rather than "buffer" since it operates on an std::string rather than a buffer. And call it "appendf" rather than "printf", since it appends to and does not replace the string's content. This mirrors string_appendf. Place the new version in gdbsupport/xml-utils.h. The code is a direct copy of buffer_xml_printf. The old version is going to disappear at some point, which is why I didn't do any effort to share code. Change-Id: I30e030627ab4970fd0b9eba3b7e8cec78fa561ba Approved-By: Pedro Alves <pedro@palves.net>
* gdbsupport: change xml_escape_text_append's parameter from pointer to referenceSimon Marchi2022-12-152-9/+9
| | | | | | | The passed in string can't be nullptr, it makes more sense to pass in a reference. Change-Id: Idc8bd38abe1d6d9b44aa227d7856956848c233b3
* Move streq and compare_cstrings to gdbsupportTom Tromey2022-12-151-0/+16
| | | | | | | | | | It seems to me that streq and compare_cstrings belong near the other string utility functions in common-utils.h; and furthermore that streq ought to be inlined. This patch makes this change. Approved-By: Simon Marchi <simon.marchi@efficios.com>
* gdb: add SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXITAndrew Burgess2022-12-141-19/+73
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After the previous commit converted symbol-lookup debug to use the new debug scheme, this commit adds SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT. The previous commit didn't add SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT because symbol-lookup debug is controlled by an 'unsigned int' rather than a 'bool' control variable, we use the numeric value to offer different levels of verbosity for symbol-lookup debug. The *_SCOPED_DEBUG_ENTER_EXIT mechanism currently relies on capturing a reference to the bool control variable, and evaluating the variable both on entry, and at exit, this is done in the scoped_debug_start_end class (see gdbsupport/common-debug.h). This commit templates scoped_debug_start_end so that the class can accept either a 'bool &' or an invokable object, e.g. a lambda function, or a function pointer. The existing scoped_debug_start_end and scoped_debug_enter_exit macros in common-debug.h are updated to support scoped_debug_enter_exit being templated, however, nothing outside of common-debug.h needs to change. I've then added SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT in symtab.h, and added a couple of token uses in symtab.c. I didn't want to add too much in this first commit, this is really about updating common-debug.h to support this new functionality. Within symtab.h I created a couple of global functions that can be used to query the status of the symbol_lookup_debug control variable, these functions are then used within the two existing macros: symbol_lookup_debug_printf symbol_lookup_debug_printf_v and also in the new SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT macro.
* fix leak in gdb_environPhilippe Waroquiers2022-11-271-0/+2
| | | | | | | | | | | | | | | | | | | | | | valgrind reports a leak when assigning a gdb_environ to another gdb_environ. The memory allocated for the target gdb_environ env variables is not released. The gdb_environ selftest reproduces the leak (see below). Fix the leak by clearing the target gdb_environ before std::move-ing the members. Tested natively and re-running all tests under valgrind. ==3261873== 4,842 bytes in 69 blocks are definitely lost in loss record 6,772 of 6,839 ==3261873== at 0x483979B: malloc (vg_replace_malloc.c:393) ==3261873== by 0x25A454: xmalloc (alloc.c:57) ==3261873== by 0x7D1E4E: xstrdup (xstrdup.c:34) ==3261873== by 0x7E2A51: gdb_environ::from_host_environ() (environ.cc:56) ==3261873== by 0x66F1C8: test_reinit_from_host_environ (environ-selftests.c:78) ==3261873== by 0x66F1C8: selftests::gdb_environ_tests::run_tests() (environ-selftests.c:285) ==3261873== by 0x7EFC43: operator() (std_function.h:622) = Approved-By: Simon Marchi <simon.marchi@efficios.com>
* gdb: new $_inferior_thread_count convenience variableAndrew Burgess2022-11-171-0/+4
| | | | | | | | | | | | Add a new convenience variable $_inferior_thread_count that contains the number of live (non-exited) threads in the current inferior. This can be used in command scripts, or breakpoint conditions, etc to adjust the behaviour for multi-threaded inferiors. This value is only stable in all-stop mode. In non-stop mode, where new threads can be started, and existing threads exit, at any time, this convenience variable can give a different value each time it is evaluated.
* Fix Cygwin build after 02d04eacJon Turney2022-11-132-3/+3
| | | | | | | | | | Commit 02d04eac "Use strwinerror in gdb/windows-nat.c" also moves strwinerror() under the USE_WIN32API conditional, which is not defined for Cygwin (and looks like it shouldn't be, as appears to imply non-POSIX and MiNGW and WinSock...) Also enable the declaration and definition of strwinerror() when __CYGWIN__ is defined.
* gdbsupport, gdb: add read_text_file_to_string, use it in ↵Simon Marchi2022-11-082-0/+41
| | | | | | | | | | | | | | | | | | | | linux_common_core_of_thread I would like to add more code to nat/linux-osdata.c that reads an entire file from /proc or /sys and processes it as a string afterwards. I would like to avoid duplicating the somewhat error-prone code that reads an entire file to a buffer. I think we should have a utility function that does that. Add read_file_to_string to gdbsupport/filestuff.{c,h}, and make linux_common_core_of_thread use it. I want to make the new function return an std::string, and because strtok doesn't play well with std::string (it requires a `char *`, std::string::c_str returns a `const char *`), change linux_common_core_of_thread to use std::string methods instead. Approved-By: Tom Tromey <tom@tromey.com> Change-Id: I1793fda72a82969c28b944a84acb953f74c9230a
* internal_error: remove need to pass __FILE__/__LINE__Pedro Alves2022-10-198-31/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently, every internal_error call must be passed __FILE__/__LINE__ explicitly, like: internal_error (__FILE__, __LINE__, "foo %d", var); The need to pass in explicit __FILE__/__LINE__ is there probably because the function predates widespread and portable variadic macros availability. We can use variadic macros nowadays, and in fact, we already use them in several places, including the related gdb_assert_not_reached. So this patch renames the internal_error function to something else, and then reimplements internal_error as a variadic macro that expands __FILE__/__LINE__ itself. The result is that we now should call internal_error like so: internal_error ("foo %d", var); Likewise for internal_warning. The patch adjusts all calls sites. 99% of the adjustments were done with a perl/sed script. The non-mechanical changes are in gdbsupport/errors.h, gdbsupport/gdb_assert.h, and gdb/gdbarch.py. Approved-By: Simon Marchi <simon.marchi@efficios.com> Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
* gdbsupport: re-generate configureSimon Marchi2022-10-091-2/+2
| | | | | | | I get this diff when re-generating configure, probably leftover from 67d1991b785 ("egrep in binutils"). Change-Id: I759c88c2bad648736d33ff98089db45c9b686356
* gdbsupport: move fileio_errno_to_host to fileio.{h,cc} and renameSimon Marchi2022-09-212-0/+57
| | | | | | | | | | gdb_bfd.c and remote.c contain identical implementations of a fileio_error -> errno function. Factor that out to gdbsupport/fileio.{h,cc}. Rename it fileio_error_to_host, for symmetry with host_to_fileio_error. Change-Id: Ib9b8807683de2f809c94a5303e708acc2251a0df
* gdbsupport: convert FILEIO_* macros to an enumSimon Marchi2022-09-212-24/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Converting from free-form macros to an enum gives a bit of type-safety. This caught places where we would assign host error numbers to what should contain a target fileio error number, for instance in target_fileio_pread. I added the FILEIO_SUCCESS enumerator, because remote.c:remote_hostio_parse_result initializes the remote_errno output variable to 0. It seems better to have an explicit enumerator than to assign a value for which there is no enumerator. I considered initializing this variable to FILEIO_EUNKNOWN instead, such that if the remote side replies with an error and omits the errno value, we'll get an errno that represents an error instead of 0 (which reprensents no error). But it's not clear what the consequences of that change would be, so I prefer to err on the side of caution and just keep the existing behavior (there is no intended change in behavior with this patch). Note that remote_hostio_parse_resul still reads blindly what the remote side sends as a target errno into this variable, so we can still end up with a nonsensical value here. It's not good, but out of the scope of this patch. Convert host_to_fileio_error and fileio_errno_to_host to return / accept a fileio_error instead of an int, and cascade the change in the whole chain that uses that. Change-Id: I454b0e3fcf0732447bc872252fa8e57d138b0e03
* gdbsupport: move include/gdb/fileio.h contents to fileio.hSimon Marchi2022-09-211-1/+109
| | | | | | | | | | | | I don't see why include/gdb/fileio.h is placed there. It's not installed by "make install", and it's not included by anything outside of gdb/gdbserver/gdbsupport. Move its content back to gdbsupport/fileio.h. I have omitted the bits inside an `#if 0`, since it's obviously not used, as well as the "limits" constants, which are also unused. Change-Id: I6fbc2ea10fbe4cfcf15f9f76006b31b99c20e5a9
* gdbsupport: change path_join parameter to array_view<const char *>Simon Marchi2022-09-212-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a GDB built with -D_GLIBCXX_DEBUG=1 reads a binary with a single character name, we hit this assertion failure: $ ./gdb -q --data-directory=data-directory -nx ./x /usr/include/c++/12.1.0/string_view:239: constexpr const std::basic_string_view<_CharT, _Traits>::value_type& std::basic_string_view<_CharT, _Traits>::operator[](size_type) const [with _CharT = char; _Traits = std::char_traits<char>; const_reference = const char&; size_type = long unsigned int]: Assertion '__pos < this->_M_len' failed. The backtrace: #3 0x00007ffff6c0f002 in std::__glibcxx_assert_fail (file=<optimized out>, line=<optimized out>, function=<optimized out>, condition=<optimized out>) at /usr/src/debug/gcc/libstdc++-v3/src/c++11/debug.cc:60 #4 0x000055555da8a864 in std::basic_string_view<char, std::char_traits<char> >::operator[] (this=0x7fffffffcc30, __pos=1) at /usr/include/c++/12.1.0/string_view:239 #5 0x00005555609dcb88 in path_join[abi:cxx11](gdb::array_view<std::basic_string_view<char, std::char_traits<char> > const>) (paths=...) at /home/simark/src/binutils-gdb/gdbsupport/pathstuff.cc:203 #6 0x000055555e0443f4 in path_join<char const*, char const*> () at /home/simark/src/binutils-gdb/gdb/../gdbsupport/pathstuff.h:84 #7 0x00005555609dc336 in gdb_realpath_keepfile[abi:cxx11](char const*) (filename=0x6060000a8d40 "/home/simark/build/binutils-gdb-one-target/gdb/./x") at /home/simark/src/binutils-gdb/gdbsupport/pathstuff.cc:122 #8 0x000055555ebd2794 in exec_file_attach (filename=0x7fffffffe0f9 "./x", from_tty=1) at /home/simark/src/binutils-gdb/gdb/exec.c:471 #9 0x000055555f2b3fb0 in catch_command_errors (command=0x55555ebd1ab6 <exec_file_attach(char const*, int)>, arg=0x7fffffffe0f9 "./x", from_tty=1, do_bp_actions=false) at /home/simark/src/binutils-gdb/gdb/main.c:513 #10 0x000055555f2b7e11 in captured_main_1 (context=0x7fffffffdb60) at /home/simark/src/binutils-gdb/gdb/main.c:1209 #11 0x000055555f2b9144 in captured_main (data=0x7fffffffdb60) at /home/simark/src/binutils-gdb/gdb/main.c:1319 #12 0x000055555f2b9226 in gdb_main (args=0x7fffffffdb60) at /home/simark/src/binutils-gdb/gdb/main.c:1344 #13 0x000055555d938c5e in main (argc=5, argv=0x7fffffffdcf8) at /home/simark/src/binutils-gdb/gdb/gdb.c:32 The problem is this line in path_join: gdb_assert (strlen (path) == 0 || !IS_ABSOLUTE_PATH (path)); ... where `path` is "x". IS_ABSOLUTE_PATH eventually calls HAS_DRIVE_SPEC_1: #define HAS_DRIVE_SPEC_1(dos_based, f) \ ((f)[0] && ((f)[1] == ':') && (dos_based)) This macro accesses indices 0 and 1 of the input string. However, `f` is a string_view of length 1, so it's incorrect to try to access index 1. We know that the string_view's underlying object is a null-terminated string, so in practice there's no harm. But as far as the string_view is concerned, index 1 is considered out of bounds. This patch makes the easy fix, that is to change the path_join parameter from a vector of to a vector of `const char *`. Another solution would be to introduce a non-standard gdb::cstring_view class, which would be a view over a null-terminated string. With that class, it would be correct to access index 1, it would yield the NUL character. If there is interest in having this class (it has been mentioned a few times in the past) I can do it and use it here. This was found by running tests such as gdb.ada/arrayidx.exp, which produce 1-char long filenames, so adding a new test is not necessary. Change-Id: Ia41a16c7243614636b18754fd98a41860756f7af
* gdbsupport: Fix config.status dependencyTsukasa OI2022-09-083-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | Commit 171fba11ab27 ("Make GDBserver abort on internal error in development mode") created a new substitution CONFIG_STATUS_DEPENDENCIES but this is used by Makefile.in (which is not regenerated by that commit). After regenerating it, it is found that CONFIG_STATUS_DEPENDENCIES value is not valid, making gdbsupport fail to build. Since the CONFIG_STATUS_DEPENDENCIES value is used in the Makefile, macro substitution must have a Makefile format but commit 171fba11ab27 used shell format "$srcdir/../bfd/development.sh". This commit fixes this issue by substituting "$srcdir" (shell format) to "$(srcdir)" (Makefile format). It preserves the dependency as Pedro intended and fixes the build problem. It also regenerates corresponding files with the maintainer mode. gdbsupport/ChangeLog: * configure.ac: Fix config.status dependency. * Makefile.in: Regenerate. * configure: Regenerate.
* gdbsupport: add wrapper around result_of and invoke_resultSimon Marchi2022-08-303-6/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When building with Clang 14 (using gcc 12 libstdc++ headers), I get: CXX dwarf2/read.o In file included from /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:94: /home/simark/src/binutils-gdb/gdb/../gdbsupport/parallel-for.h:142:21: error: 'result_of<(lambda at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7124:5) (__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter> *, std::__cxx1998::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>>, std::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>, std::random_access_iterator_tag>, __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter> *, std::__cxx1998::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>>, std::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>, std::random_access_iterator_tag>)>' is deprecated: use 'std::invoke_result' instead [-Werror,-Wdeprecated-declarations] = typename std::result_of<RangeFunction (RandomIt, RandomIt)>::type; ^ /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7122:14: note: in instantiation of function template specialization 'gdb::parallel_for_each<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter> *, std::__cxx1998::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>>, std::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>, std::random_access_iterator_tag>, (lambda at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7124:5)>' requested here = gdb::parallel_for_each (1, per_bfd->all_comp_units.begin (), ^ /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../include/c++/12.1.1/type_traits:2597:9: note: 'result_of<(lambda at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7124:5) (__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter> *, std::__cxx1998::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>>, std::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>, std::random_access_iterator_tag>, __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter> *, std::__cxx1998::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>>, std::vector<std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>>, std::random_access_iterator_tag>)>' has been explicitly marked deprecated here { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result"); ^ /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../include/c++/12.1.1/x86_64-pc-linux-gnu/bits/c++config.h:120:45: note: expanded from macro '_GLIBCXX17_DEPRECATED_SUGGEST' # define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) ^ /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../include/c++/12.1.1/x86_64-pc-linux-gnu/bits/c++config.h:96:19: note: expanded from macro '_GLIBCXX_DEPRECATED_SUGGEST' __attribute__ ((__deprecated__ ("use '" ALT "' instead"))) ^ It complains about the use of std::result_of, which is deprecated in C++17 and removed in C++20: https://en.cppreference.com/w/cpp/types/result_of Given we'll have to transition to std::invoke_result eventually, make a GDB wrapper to mimimc std::invoke_result, which uses std::invoke_result for C++ >= 17 and std::result_of otherwise. This way, it will be easy to remove the wrapper in the future, just replace gdb:: with std::. Tested by building with gcc 12 in -std=c++11 and -std=c++17 mode, and clang in -std=c++17 mode (I did not test fully with clang in -std=c++11 mode because there are other unrelated issues). Change-Id: I50debde0a3307a7bc67fcf8fceefda51860efc1d
* gdbsupport: fix gdb::optional compilation with C++11 && _GLIBCXX_DEBUGSimon Marchi2022-08-261-2/+2
| | | | | | | | | | | | | | | | | | | | Similar to 911438f9f4 ("gdbsupport: fix array-view compilation with c++11 && _GLIBCXX_DEBUG"), but for gdb::optional. I get this error when building with Clang 14 and -std=c++11: CXX agent.o In file included from /home/simark/src/binutils-gdb/gdbsupport/agent.cc:20: In file included from /home/simark/src/binutils-gdb/gdbsupport/common-defs.h:210: In file included from /home/simark/src/binutils-gdb/gdbsupport/common-debug.h:23: /home/simark/src/binutils-gdb/gdbsupport/../gdbsupport/gdb_optional.h:213:5: error: use of this statement in a constexpr function is a C++14 extension [-Werror,-Wc++14-extensions] gdb_assert (this->has_value ()); ^ /home/simark/src/binutils-gdb/gdbsupport/gdb_assert.h:35:3: note: expanded from macro 'gdb_assert' ((void) ((expr) ? 0 : \ ^ Change-Id: If0cf55607fc9dbd1925ccb97cd9abbf8993ff264
* gdb, gdbsupport: configure: factor out yes/no/auto value checkingSimon Marchi2022-08-261-0/+28
| | | | | | | | | | | | | | Factor out the code that checks that a value is yes/no or yes/no/auto. Add two macros to gdbsupport/common.m4 and use them in gdb/configure.ac I inspected the changes to configure. Other than whitespace changes, we have some benign changes to the error messages (one of them had an error actually). There are changes to the --enable-source-highlight and --enable-libbacktrace handling, but setting enable_source_highlight / enable_libbacktrace was not really useful anyway, they already had the right value. Change-Id: I92587aec36874309e1605e2d60244649f09a757a
* gdb_do_one_event: use integer test syntaxPatrick Monnerat2022-08-191-2/+2
| | | | Timeout is an int, not a bool.
* gdbsupport/event-loop: add a timeout parameter to gdb_do_one_eventPatrick Monnerat2022-08-182-11/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since commit b2d8657, having a per-interpreter event/command loop is not possible anymore. As Insight uses a GUI that has its own event loop, gdb and GUI event loops have then to be "merged" (i.e.: work together). But this is problematic as gdb_do_one_event is not aware of this alternate event loop and thus may wait forever. A solution is to delegate GUI events handling to the gdb events handler. Insight uses Tck/Tk as GUI and the latter offers a "notifier" feature to implement such a delegation. The Tcl notifier spec requires the event wait function to support a timeout parameter. Unfortunately gdb_do_one_event does not feature such a parameter. This timeout cannot be implemented externally with a gdb timer, because it would become an event by itself and thus can cause a legitimate event to be missed if the timeout is 0. Tcl implements "idle events" that are (internally) triggered only when no other event is pending. For this reason, it can call the event wait function with a 0 timeout quite often. This patch implements a wait timeout to gdb_do_one_event. The initial pending events monitoring is performed as before without the possibility to enter a wait state. If no pending event has been found during this phase, a timer is then created for the given timeout in order to re-use the implemented timeout logic and the event wait is then performed. This "internal" timer only limits the wait time and should never be triggered. It is deleted upon gdb_do_one_event exit. The new parameter defaults to "no timeout" (-1): as it is used by Insight only, there is no need to update calls from the gdb source tree.
* Use strwinerror in gdb/windows-nat.cTom Tromey2022-08-162-0/+70
| | | | | | | | | | | | When working on windows-nat.c, it's useful to see an error message in addition to the error number given by GetLastError. This patch moves strwinerror from gdbserver to gdbsupport, and then updates windows-nat.c to use it. A couple of minor changes to strwinerror (constify the return type and use the ARRAY_SIZE macro) are also included.
* [gdbsupport] Add task size parameter in parallel_for_eachTom de Vries2022-08-051-22/+91
| | | | | | | Add a task_size parameter to parallel_for_each, defaulting to nullptr, and use the task size to distribute similarly-sized chunks to the threads. Tested on x86_64-linux.
* Introduce gdb::make_function_viewPedro Alves2022-08-051-0/+127
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds gdb::make_function_view, which lets you create a function view from a callable without specifying the function_view's template parameter. For example, this: auto lambda = [&] (int) { ... }; auto fv = gdb::make_function_view (lambda); instead of: auto lambda = [&] (int) { ... }; gdb::function_view<void (int)> fv = lambda; It is particularly useful if you have a template function with an optional function_view parameter, whose type depends on the function's template parameters. Like: template<typename T> void my_function (T v, gdb::function_view<void(T)> callback = nullptr); For such a function, the type of the callback argument you pass must already be a function_view. I.e., this wouldn't compile: auto lambda = [&] (int) { ... }; my_function (1, lambda); With gdb::make_function_view, you can write the call like so: auto lambda = [&] (int) { ... }; my_function (1, gdb::make_function_view (lambda)); Unit tests included. Tested by building with GCC 9.4, Clang 10, and GCC 4.8.5, on x86_64 GNU/Linux, and running the unit tests. Change-Id: I5c4b3b4455ed6f0d8878cf1be189bea3ee63f626
* [gdb] Add debug_{exp,val}Tom de Vries2022-08-051-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | When debugging cc1 I heavily rely on simple one-parameter debug functions that allow me to inspect a variable of a common type, like: - debug_generic_expr - debug_gimple_stmt - debug_rtx and I miss similar functions in gdb. Add functions to dump variables of types 'value' and 'expression': - debug_exp, and - debug_val. Tested on x86_64-linux, by breaking on varobj_create, and doing: ... (gdb) call debug_exp (var->root->exp.get ()) &"Operation: OP_VAR_VALUE\n" &" Block symbol:\n" &" Symbol: aaa\n" &" Block: 0x2d064f0\n" (gdb) ... and: ... (gdb) call debug_val (value) &"5" (gdb) ...
* struct packed: Add fallback byte array implementationPedro Alves2022-07-251-3/+48
| | | | | | | | | | | | Attribute gcc_struct is not implemented in Clang targeting Windows, so add a fallback standard-conforming implementation based on arrays. I ran the testsuite on x86_64 GNU/Linux with this implementation forced, and saw no regressions. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29373 Change-Id: I023315ee03622c59c397bf4affc0b68179c32374
* struct packed: Unit tests and more operatorsPedro Alves2022-07-251-30/+49
| | | | | | | | | | | | | | For PR gdb/29373, I wrote an alternative implementation of struct packed that uses a gdb_byte array for internal representation, needed for mingw+clang. While adding that, I wrote some unit tests to make sure both implementations behave the same. While at it, I implemented all relational operators. This commit adds said unit tests and relational operators. The alternative gdb_byte array implementation will come next. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29373 Change-Id: I023315ee03622c59c397bf4affc0b68179c32374
* struct packed: Use gcc_struct on WindowsPedro Alves2022-07-251-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Building GDB on mingw/gcc hosts is currently broken, due to a static assertion failure in gdbsupport/packed.h: In file included from ../../../../../binutils-gdb/gdb/../gdbsupport/common-defs.h:201, from ../../../../../binutils-gdb/gdb/defs.h:28, from ../../../../../binutils-gdb/gdb/dwarf2/read.c:31: ../../../../../binutils-gdb/gdb/../gdbsupport/packed.h: In instantiation of 'packed<T, Bytes>::packed(T) [with T = dwarf_unit_type; long long unsigned int Bytes = 1]': ../../../../../binutils-gdb/gdb/dwarf2/read.h:181:74: required from here ../../../../../binutils-gdb/gdb/../gdbsupport/packed.h:41:40: error: static assertion failed 41 | gdb_static_assert (sizeof (packed) == Bytes); | ~~~~~~~~~~~~~~~~^~~~~~~~ ../../../../../binutils-gdb/gdb/../gdbsupport/gdb_assert.h:27:48: note: in definition of macro 'gdb_static_assert' 27 | #define gdb_static_assert(expr) static_assert (expr, "") | ^~~~ ../../../../../binutils-gdb/gdb/../gdbsupport/packed.h:41:40: note: the comparison reduces to '(4 == 1)' 41 | gdb_static_assert (sizeof (packed) == Bytes); | ~~~~~~~~~~~~~~~~^~~~~~~~ The issue is that mingw gcc defaults to "-mms-bitfields", which affects how bitfields are laid out. We can however tell GCC that we want the regular GCC layout instead using attribute gcc_struct. Attribute gcc_struct is not implemented in "clang -target x86_64-pc-windows-gnu", so that will need a different fix. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29373 Change-Id: I023315ee03622c59c397bf4affc0b68179c32374
* gdbsupport: add checked_static_castAndrew Burgess2022-07-211-0/+68
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit was inspired by these mailing list posts: https://sourceware.org/pipermail/gdb-patches/2022-June/190323.html https://sourceware.org/pipermail/gdb-patches/2022-April/188098.html The idea is to add a new function gdb::checked_static_cast, which can, in some cases, be used as a drop-in replacement for static_cast. And so, if I previously wrote this: BaseClass *base = get_base_class_pointer (); DerivedClass *derived = static_cast<DerivedClass *> (base); I can now write: BaseClass *base = get_base_class_pointer (); DerivedClass *derived = gdb::checked_static_cast<DerivedClass *> (base); The requirement is that BaseClass and DerivedClass must be polymorphic. The benefit of making this change is that, when GDB is built in developer mode, a run-time check will be made to ensure that `base` really is of type DerivedClass before the cast is performed. If `base` is not of type DerivedClass then GDB will assert. In a non-developer build gdb::checked_static_cast is equivalent to a static_cast, and there should be no performance difference. This commit adds the support function, but does not make use of this function, a use will be added in the next commit. Co-Authored-By: Pedro Alves <pedro@palves.net> Co-Authored-By: Tom Tromey <tom@tromey.com>
* [gdbsupport] Fix type of parallel_for_each_debugTom de Vries2022-07-211-1/+1
| | | | | | | When I changed the initialization of parallel_for_each_debug from 0 to false, I forgot to change the type from int to bool. Fix this. Tested by rebuilding on x86_64-linux.
* [gdbsupport] Improve thread scheduling in parallel_for_eachTom de Vries2022-07-181-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When running a task using parallel_for_each, we get the following distribution: ... Parallel for: n_elements: 7271 Parallel for: minimum elements per thread: 10 Parallel for: elts_per_thread: 1817 Parallel for: elements on worker thread 0 : 1817 Parallel for: elements on worker thread 1 : 1817 Parallel for: elements on worker thread 2 : 1817 Parallel for: elements on worker thread 3 : 0 Parallel for: elements on main thread : 1820 ... Note that there are 4 active threads, and scheduling elts_per_thread on each of those handles 4 * 1817 == 7268, leaving 3 "left over" elements. These leftovers are currently handled in the main thread. That doesn't seem to matter much for this example, but for say 10 threads and 99 elements, you'd have 9 threads handling 9 elements and 1 thread handling 18 elements. Instead, distribute the left over elements over the worker threads, such that we have: ... Parallel for: elements on worker thread 0 : 1818 Parallel for: elements on worker thread 1 : 1818 Parallel for: elements on worker thread 2 : 1818 Parallel for: elements on worker thread 3 : 0 Parallel for: elements on main thread : 1817 ... Tested on x86_64-linux.