clang BlocksRuntime embeds 'obsolete compiler' warning in executable when using __block - c++

#include <stdio.h>
#include <Block.h>
int main()
{
__block int x = 5;
^{printf("x is %i\n", x);}();
}
When I use clang to compile a c (or c++) program that uses both clang's blocks and the __block type specifier, no compiler warnings are produced, even using -Wall and -Wpedantic. The program also runs as expected. However, if I open the executable using a text editor, I find this block of text (extracted using 'strings' command):
Block_release called upon a stack Block: %p, ignored
_Block_byref_release: Block byref data structure at %p underflowed
Block compiled by obsolete compiler, please recompile source for this Block
descriptor->dispose helper: %p
byref data block %p contents:
^%p (new layout) =
isa?: %p
refcount: %u
invoke: %p
descriptor: %p
descriptor->reserved: %lu
descriptor->size: %lu
descriptor->copy helper: %p
forwarding: %p
flags: 0x%x
size: %d
copy helper: %p
dispose helper: %p
NULL passed to _isa: stack Blockisa: malloc heapisa: GC heap Bloisa: global Blocisa: finalizing
The problem is that I am using the latest version of clang - hardly an 'obsolete' compiler. I am on Linux (musl) and I installed the BlocksRuntime from https://github.com/mackyle/blocksruntime. I also found the piece of code that generates the warning here - https://github.com/mackyle/blocksruntime/blob/master/BlocksRuntime/runtime.c#L629
λ: clang --version
clang version 10.0.0
Target: x86_64-unknown-linux-musl
Thread model: posix
InstalledDir: /bin
λ: uname -a
Linux thinkpad 5.7.9_1 #1 SMP Thu Jul 16 10:02:50 UTC 2020 x86_64 GNU/Linux
Is it safe to ignore this warning? If not, what can I do about it?

I've just realized that the warning is probably meant to be a runtime error stored as a string in the executable, which means that there is no problem. Disassembling seems to support this idea - radare2 shows the string in the .rodata section:
I really should have though of that earlier...

Related

__transaction_atomic without transactional memory support enabled

I was just compiling C/C++ code using __transaction_atomic but compiler error occurred
[Error] __transaction_atomic' without transactional memory support enabled
Code is:
#include <stdio.h>
int main()
{
int i = 0;
__transaction_atomic
{
i++;
}
return 0;
}
How to figure it out? My compiler is GCC 4.9
You should compile code with transaction memory support enabled.
From here
Compiling a TM program with GCC To enable the support for TM, the
'-fgnu-tm' compiler directive has to be added to the compilation
command line. Example: gcc -Wall -fgnu-tm -O3 -o ll ll.c Note that
with the optimization level 0 (-O0), some of the TM optimization are
disabled (RaR, RaW, RfW, WaR, WaW, optimized stack memory barriers).

OS X get process's memory programmatically

I am trying to get the memory used by another process. From what I've read it seems like I need to use mach_vm_regeion. I found some code on a random forum and tried compiling to make sure I understood how it was working, but I get this error.
error: use of undeclared identifier 'mach_vm_region'
kret = mach_vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_regio...
^
1 error generated.
I am on OS X 10.11.2 compiling using clang++ --std=c++11 file.cpp.
clang --version returns
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.2.0
Thread model: posix
You don't have the correct includes. I find that
#include <mach/mach.h>
#include <mach/mach_vm.h>
works. You also need to change: vm_size_t size to mach_vm_size_t size, which is the type the function expects. Then it compiles and works as expected (when run as root, as the comment suggests).

Getting weird result by using %I64u inside Mingw-w64

This is my code :
Note : \n inside scanf is my way to prevent trailing newline problem. That isn't best solution but i'm using it too much and currently it becoming my habit. :-)
...
int main()
{
unsigned long long int input[2], calc_square;
while(scanf("\n%I64u %I64u", input[0], input[1]) == 2)
{
printf("%I64u %I64u\n", input[0], input[1]);
...
My expected input and program result is :
Input :
89 89
For output, instead of printing back 89, it show this output :
I64u I64u
I'm using g++ (GCC) 4.9.1 from MSYS2 package. Noted that g++ because there are some portion of my code currently using C++ STL.
Edited : I changed my code by using standard %llu instead of %I64u, and here is my expected input and program result :
Input
89 89
For output, it's kind a weird result :
25769968512 2337536
This code is wrong:
while(scanf("\n%I64u %I64u", input[0], input[1]) == 2)
input[0] and input[1] each have type unsigned long long, but they are required to have type unsigned long long * (pointer to unsigned long long) for scanf operations. I'm unsure if MinGW supports checking printf and scanf format specifiers, but ordinary GCC is capable of detecting these kinds of errors at compile time as long as you enable the proper warnings. I highly recommend always compiling with as high of a warning level as you possibly can, such as -Wall -Wextra -Werror -pedantic in the most extreme case.
You need to pass in the address of these variables:
while(scanf("\n%I64u %I64u", &input[0], &input[1]) == 2)
// ^ ^
// | |
I suspect you have been using MSYS2's GCC which isn't a native Windows compiler, and doesn't support the MS-specific %I64 format modifiers (MSYS2's GCC is very much like Cygwin's GCC).
If you wanted to use MinGW-w64 GCC, you should have launched mingw64_shell.bat or mingw32_shell.bat and have the appropriate toolchain installed:
pacman -S mingw-w64-i686-toolchain
or
pacman -S mingw-w64-x86_64-toolchain
With that done, you can safely use either modifier on any Windows version dating back to Windows XP SP3 provided you pass -D__USE_MINGW_ANSI_STDIO=1.
FWIW, I avoid using the MS-specific modifiers and always pass -D__USE_MINGW_ANSI_STDIO=1
Finally, annoyingly, your sample doesn't work when launched from the MSYS2 shell due to mintty not being a proper Windows console; you need to run it from cmd.exe

Problems throwing and catching exceptions on OS X with -fno-rtti

The issue is somewhat similar to this question but the accepted answer does not really propose a solution or workaround.
In our project, we have a dylib and the main executalble. The dylib is compiled with -fno-rtti, while the executable does use RTTI. The problem happens when an exception (e.g. std::bad_alloc) is thrown from the dylib and is caught in the exe.
(Before you yell "exceptions need RTTI so you must have it on!", please note that the RTTI necessary for exceptions is always generated regardless of the -frtti or -fno-rtti setting. This is actually documented in the -fno-rtti flag description. The issue on OS X is that it's not generated in the same way)
After some investigation, the following was discovered:
In the dylib (-fno-rtti), there is a local copy of the exception's RTTI structures; in particular, the __ZTISt9bad_alloc symbol (typeinfo for std::bad_alloc).
The exe (-frtti) imports the typeinfo symbol from libstdc++.6.dylib and does not have a local copy
Since the exception handling code relies on comparing typeinfo pointers to determine exception match, the matching fails, and only the catch(...) succeeds.
So far I see the following options:
1) compile everything, or at least the files that throw and catch exceptions, with -frtti. This is doable but I don't like the idea of generating RTTI for everything even if we don't use it; and the list of files which work with exceptions is prone to get stale.
2) when linking the dylib, somehow make the linker throw away the weak exception definition from the object file and use the one from libstdc++.6.dylib. So far I was not successful.
3) ???
I made a small test illustrating the problem.
--- throw.cpp ---
#include <iostream>
#if defined(__GNUC__)
#define EXPORT __attribute__((visibility("default")))
#else
#define EXPORT __declspec(dllexport)
#endif
EXPORT void dothrow ()
{
std::cout << "before throw" << std::endl;
throw std::bad_alloc();
}
--- main.cpp ---
#include <stdio.h>
#include <iostream>
#if defined(__GNUC__)
#define IMPORT extern
#else
#define IMPORT __declspec(dllimport)
#endif
IMPORT void dothrow ();
int main (void) {
try {
std::cout << "trying lib->main exception" << std::endl;
dothrow ();
}
catch ( const std::bad_alloc& )
{
std::cout << "caught bad_alloc in main - good." << std::endl;
}
catch (...)
{
std::cout << "caught ... in main - bad!" << std::endl;
}
}
--- makefile ---
# for main exe
CFLAGS_RTTI=-m32 -frtti -fvisibility=hidden -fvisibility-inlines-hidden -shared-libgcc -funwind-tables
# for dylib
CFLAGS_NORTTI=-m32 -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -shared-libgcc
# for linking; some switches which don't help
CLFLAGS=-Wl,-why_live,-warn_commons,-weak_reference_mismatches,error,-commons,error
all: test
test: libThrow.dylib main.o
g++ $(CFLAGS_RTTI) -o test main.o -lthrow -L./ $(CLFLAGS)
main.o: main.cpp
g++ $(CFLAGS_RTTI) -c -o main.o main.cpp
throw.o: throw.cpp
g++ $(CFLAGS_NORTTI) -c -o throw.o throw.cpp
libThrow.dylib: throw.o
g++ $(CFLAGS_NORTTI) -dynamiclib -o libThrow.dylib throw.o
clean:
rm test main.o throw.o
Running:
$ ./test
trying lib->main exception
before throw
caught ... in main - bad!
Symbols of the files involved:
$ nm -m throw.o | grep bad_alloc
000001be (__TEXT,__textcoal_nt) weak private external __ZNSt9bad_allocC1Ev
000001be (__TEXT,__textcoal_nt) weak private external __ZNSt9bad_allocC1Ev
00000300 (__TEXT,__eh_frame) weak private external __ZNSt9bad_allocC1Ev.eh
(undefined) external __ZNSt9bad_allocD1Ev
00000290 (__DATA,__const_coal) weak external __ZTISt9bad_alloc
000002a4 (__TEXT,__const_coal) weak external __ZTSSt9bad_alloc
(undefined) external __ZTVSt9bad_alloc
$ nm -m libThrow.dylib | grep bad_alloc
00000ce6 (__TEXT,__text) non-external __ZNSt9bad_allocC1Ev
(undefined) external __ZNSt9bad_allocD1Ev (from libstdc++)
00001050 (__DATA,__const) weak external __ZTISt9bad_alloc
00000e05 (__TEXT,__const) weak external __ZTSSt9bad_alloc
(undefined) external __ZTVSt9bad_alloc (from libstdc++)
$ nm -m main.o | grep bad_alloc
(undefined) external __ZTISt9bad_alloc
$ nm -m test | grep bad_alloc
(undefined) external __ZTISt9bad_alloc (from libstdc++)
Note: similar compilation options on Linux and Windows works fine. I can throw exceptions from a shared object/dll and catch them in the main exe, even if they're compiled with different -frtti/-fno-rtti options.
EDIT: here's how I ended up solving it for the specific case of bad_alloc:
#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
#define throw_nomem std::__throw_bad_alloc
#else
#define throw_nomem throw std::bad_alloc
#endif
EXPORT void dothrow ()
{
std::cout << "before throw" << std::endl;
throw_nomem();
}
The function __throw_bad_alloc is imported from libstdc++.6.dylib and so always throws a correct type.
You can simply move all your "throw exceptions" infrastructure to the helper library with -frtti enabled - and link it to other stuff. Without actual code it's hard to tell, if this decomposition is possible or not.
Here is some sample code:
// Thrower.cc
void DoThrow() {
throw std::bad_alloc;
}
// LibraryNoRTTI.cc
void f() {
DoThrow();
}
// main.cc
int main() {
try {
f();
}
catch(std::bad_alloc&) {}
return 0;
}
The simplest way is to move all your throw invocations to the separate functions with appropriate types, like: throw std::logical_error("message"); goes to void ThrowLogicError(const std::string& message) { ... }
If there is a problem with encapsulation (private exception classes), then you may make friends with throwing functions.
If you still want to use (throw/catch) exceptions inside the non-rtti library, then you have to make separation between internal exceptions and exceptions used in your library API.
The good way is to use native C++ throw-catch for internal purposes - and then rethrow some exceptions, using rtti-based library functions, to the outside - according to your interface:
// Thrower.cc
void Rethrow(const std::exception& e) {
throw e;
}
// LibraryNoRTTI.cc
namespace {
void internal_stuff() {
throw std::logical_error("something goes wrong!");
}
} // namespace
// You even may explicitly specify the thrown exceptions in declaration:
void f() throw(std::logical_error) {
try {
internal_stuff();
}
catch(std::exception& e) {
Rethrow(std::logical_error(std::string("Internal error: ") + e.what());
}
}
Start Edit March 4, 2014
I think the Clang++ compiler has a better chance of obtaining the desired exception handling. I have found this Stack Overflow post: Clang and the default compiler in OS X Lion. The post has helpful script lines for modifying ~/.bashrc to change the system default compiler settings on Snow Leopard and how to use the LLVM GCC. For Clang, add inside the ~/.bashrc:
# Set Clang as the default compiler for the system
export CC=clang
export CFLAGS=-Qunused-arguments
export CPPFLAGS=-Qunused-arguments
If the c++ symbolic link is not present, either call clang++ directly or add the c++ link as desired (e.g.
ln -s /usr/bin/clang++ c++
). It is a good idea to check all symbolic links within the /usr/bin by running:
ls -l `which lynx` | more
On my Mavericks command line tools installation c++ points to clang++ and cc points to clang. The g++ compiler version says:
$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx- include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
The clang++ complier version says:
$clang++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
Notice that the g++ include directory path is set to /usr/include/c++/4.2.1, probably not the include path needed to resolve the issue.
MacPorts: Hopefully the Answer for any OS X version
The best solution I can find to obtain any Clang++ compiler version for any OS X version is to use the open source tool called MacPorts. There is extensive documentation in the MacPorts Guide. The application is called port and can be installed from an OS X installation package or obtain the source code and compile locally. The following is from installing MacPorts onto Snow Leopard. The other OS X versions should be similar. After obtaining MacPorts for Snow Leopard, run the port search command to observe all the different clang related ports available. For example, it looks like this:
$port search clang
The partial list of search results from Snow Leopard 10.6.8 is:
clang-2.9 #2.9_13 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.0 #3.0_12 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.1 #3.1_7 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.2 #3.2_2 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.3 #3.3_2 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.4 #3.4 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.5 #3.5-r202097 (lang)
C, C++, Objective C and Objective C++ compiler
clang_select #0.1 (sysutils)
common files for selecting default clang version
Then I successfully installed clang-3.3 with: sudo port install clang-3.3. After this completes, see the available versions by typing port select --list clang. Then run the
sudo port select --set clang mp-clang-3.3
or similar. When I execute clang++ --version it says (as expected):
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin10.8.0
Thread model: posix
Same for when the clang --version command is executed (after closing and restarting the terminal):
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin10.8.0
Thread model: posix
There are MacPorts installation packages for many OS X versions (e.g. Leopard, Snow Leopard, Lion, Mountain Lion, Mavericks, etc.). I did not go any further back than Leopard with my search. If using an OS X older than Leopard, please review the MacPorts site thoroughly.
If curious about details on where to find Xcode 4.2 (or used to be able to obtain it), I have found this post regarding obtaining Xcode 4.2 for Snow Leopard Xcode 4.2 download for Snow Leopard. Then these two additional ones: Can i use the latest features of C++11 in XCode 4 or OSX Lion? [duplicate] and Can I use C++11 with Xcode?. After trying a couple links to see if the 4.2 Xcode remains available for Snow Leopard, no joy.
More than likely the MacPorts libc++ installation will be necessary to have full C++11 support. To install the more recent version, execute sudo port install libcxx. The contents of the /usr/lib will be overwritten with the current C++11 libraries (as necessary per MacPorts Ticket #42385: libcxx/libcxxabi: OS update can render system unusable
If libc++ still appears to be lacking, try this: "libc++" C++ Standard Library. Then use this:
$ export TRIPLE=-apple-
$ export MACOSX_DEPLOYMENT_TARGET=10.6
$ ./buildit
from How to build libc++ with LLVM/Clang 3.3 on Mac OS X 10.6 "Snow Leopard".
On OS X Lion, Mountain Lion, and Mavericks, they all have recent independent command line tools downloads on the Apple Developer site. The Clang version may be older than what one needs, so be sure to confirm which C++11 features are needed when using the Developer site command line tools' Clang.
End Edit March 4, 2014
The above macro detection may need to change from __GNUC__ to __clang__ or __clang_version__. It all depends on what the predefined compiler macros are for each OS X compiler, and the best way to detect as needed here. The Stack Overflow answer at: What predefined macro can I use to detect clang? should be helpful in configuring the command line to obtain them (e.g. clang++ -dM -E -x c /dev/null).
I have noticed when running the preceding example command that there is a predefined macro called __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__. On the Mavericks clang++, the macro value is 1090. It might be necessary to have a family of #ifdef logic to set the appropriate EXPORT macro for each OS X clang++ compiler.
Well, even though I have accepted an answer it did not solve all problems. So I'm writing down the solution which did work in the end.
I made a small tool for post-processing the object files and marking the local symbols as UNDEF. This forces the linker to use definitions from libstdc++ and not local ones from the file. The basic approach of the tool is:
load the Mach-O header
walk the load commands and find the LC_SYMTAB command
load the list of symbols (struct nlist) and the strings
walk the symbols and look for those that we need (e.g. __ZTISt9bad_alloc)
set the found symbols' type to N_UNDF|N_EXT.
after processing, write the modified symbol table back to the file.
(I also made a similar implementation for ELF)
I post-process any file that's using std exceptions, either for throwing or for catching. To make sure the file list does not go stale, I added a post-link check for unwanted local symbols using nm.
This seems to resolve all the problems I've had so far.

Non-ASCII wchar_t literals under LLVM

I've migrated an Xcode iOS project from Xcode 3.2.6 to 4.2. Now I'm getting warnings when I try to initialize a wchar_t with a literal with a non-ASCII character:
wchar_t c1;
if(c1 <= L'я') //That's Cyrillic "ya"
The messages are:
MyFile.cpp:148:28: warning: character unicode escape sequence too long for its type [2]
MyFile.cpp:148:28: warning: extraneous characters in wide character constant ignored [2]
And the literal does not work as expected - the comparison misfires.
I'm compiling with -fshort-wchar, the source file is in UTF-8. The Xcode editor displays the file fine. It compiled and worked on GCC (several flavors, including Xcode 3), worked on MSVC. Is there a way to make LLVM compiler recognize those literals? If not, can I go back to GCC in Xcode 4?
EDIT: Xcode 4.2 on Snow Leopard - long story why.
EDIT2: confirmed on a brand new project. File extension does not matter - same behavior in .m files. -fshort-wchar does not affect it either. Looks like I've gotta go back to GCC until I can upgrade to a version of Xcode where this is fixed.
Not an answer, but hopefully helpful information — I could not reproduce the problem with clang 4.0 (Xcode 4.5.1):
$ uname -a
Darwin air 12.2.0 Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64 x86_64
$ env | grep LANG
LANG=en_US.UTF-8
$ clang -v
Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
wchar_t c1 = 0;
printf("sizeof(c1) == %lu\n", sizeof(c1));
printf("sizeof(L'Я') == %lu\n", sizeof(L'Я'));
if (c1 < L'Я') {
printf("Я люблю часы Заря!\n");
} else {
printf("Что за....?\n");
}
return EXIT_SUCCESS;
}
$ clang -Wall -pedantic ./test.c
$ ./a.out
sizeof(c1) == 4
sizeof(L'Я') == 4
Я люблю часы Заря!
$ clang -Wall -pedantic ./test.c -fshort-wchar
$ ./a.out
sizeof(c1) == 2
sizeof(L'Я') == 2
Я люблю часы Заря!
$
The same behavior is observed with clang++ (where wchar_t is built-in type).
If in fact the source is UTF-8 then this isn't correct behavior. However I can't reproduce the behavior in the most recent version of Xcode
MyFile.cpp:148:28: warning: character unicode escape sequence too long for its type [2]
This error should be refering to a 'Universal Character Name' (UCN), which looks like "\U001012AB" or "\u0403". It indicates that the value represented by the escape sequence is larger than the enclosing literal type is capable of holding. For example if the codepoint value requires more than 16 bits then a 16 bit wchar_t will not be able to hold the value.
MyFile.cpp:148:28: warning: extraneous characters in wide character constant ignored [2]
This indicates that the compiler thinks there's more than one codepoint represented inside a wide character literal. E.g. L'ab'. The behavior is implementation defined and both clang and gcc simply use the last codepoint value.
The code you show shouldn't trigger either of these, at least in clang. The first because that applies only to UCNs, let alone the fact that 'я' fits easily within a single 16-bit wchar_t; and the second because he source code encoding is always taken to be UTF-8 and it will see the UTF-8 multibyte representation of 'я' as a single codepoint.
You might recheck and ensure that the source actually is UTF-8. Then you should check that you're using an up-to-date version of Xcode. You can also try switching the compiler in your project settings > Compile for C/C++/Objective-C
I dont have an answer to your specific question, but wanted to point out that llvm-gcc has been permanently discontinued. In my experience in dealing with delta's between Clang and llvm-gcc, and gcc, Clang is often correct with regards to the C++ specification even if that behavior is surprising.