Skip to content
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

iOS ARM64 : Invalid access: Can not convert empty value. #4393

Closed
mbhaskar98 opened this issue Jan 11, 2024 · 12 comments · Fixed by #4394
Closed

iOS ARM64 : Invalid access: Can not convert empty value. #4393

mbhaskar98 opened this issue Jan 11, 2024 · 12 comments · Fixed by #4394
Assignees

Comments

@mbhaskar98
Copy link

Describe the bug
This bug is similar to this - #3331 but on iOS. Exact same config is failing.

Exact same code snippet and same except as provided in the description of the above bug.
Only in Release mode
-fvisibility=hidden compiler flags
ENABLE_TESTABILITY set to NO

To Reproduce
NA

Expected behavior
Json parsing should succeed.

Logs
NA

Screenshots
NA

Please add relevant environment information:

  • iOS-16
  • POCO Version - 1.11.7
@mbhaskar98 mbhaskar98 added the bug label Jan 11, 2024
@matejk
Copy link
Contributor

matejk commented Jan 11, 2024

@mbhaskar98, can you please test with version 1.13 and provide a simple code example that demonstrates the problem.

@mbhaskar98
Copy link
Author

mbhaskar98 commented Jan 11, 2024

image

Poco 1.13.0 not able to get it working.
There are multiple files which are throwing this similar error (related to std namespace not found) .

Second type of error
image

Based on release notes made sure to keep C++ version gnu++17 and C gnu11
https://docs.pocoproject.org/current/99100-ReleaseNotes.html

Compilation command -

DARWIN_CFLAGS="-D_DARWIN_UNLIMITED_SELECT -DFD_SETSIZE=65536"

./configure --config=iPhone-clang --static --no-tests --no-samples --omit=CppUnit,Encodings,NetSSL_Win,Data,Data/SQLite,Data/ODBC,Data/MySQL,Data/PostgreSQL,PageCompiler,PageCompiler/File2Page,JWT,PDF,CppParser,MongoDB,Redis,Prometheus,ActiveRecord,ActiveRecord/Compiler,PocoDoc,ProGen --cflags="$DARWIN_CFLAGS" --include-path=$OPENSSL_INCLUDE_PATH_PATH
make IPHONE_SDK_VERSION_MIN=12.0 POCO_TARGET_OSARCH=arm64 -j6

@mbhaskar98
Copy link
Author

Basic example

https://github.com/mbhaskar98/poco-issue.git

In case you want to rebuild poco,

open terminal
cd to <project_root>/library-testing/poco_1_13
./buildPoco.sh

@matejk
Copy link
Contributor

matejk commented Jan 12, 2024

I managed to reproduce the problem on macOS also by modifying CMakeLists.txt (#3331).

@mbhaskar98
Copy link
Author

@matejk could you please provide list of classes that would require *_API directives changes so that we could make the same changes in our Poco code for the time being as updating to 1.13 would be a big task at this point.

@matejk
Copy link
Contributor

matejk commented Jan 12, 2024

I am working on it.

@mbhaskar98
Copy link
Author

Found something which is atleast causing issues with 1.11.7.

Here json value is set

void ParserImpl::handle() { enum json_type type = json_next(_pJSON); switch (type) { case JSON_DONE: return; case JSON_NULL: _pHandler->null(); break; case JSON_TRUE: if (_pHandler) _pHandler->value(true); break; case JSON_FALSE: if (_pHandler) _pHandler->value(false); break; case JSON_NUMBER: if (_pHandler) { std::string str(json_get_string(_pJSON, NULL)); if (str.find(_decimalPoint) != str.npos || str.find('e') != str.npos || str.find('E') != str.npos) { _pHandler->value(NumberParser::parseFloat(str)); } else { Poco::Int64 val; if (NumberParser::tryParse64(str, val)) _pHandler->value(val); else _pHandler->value(NumberParser::parseUnsigned64(str)); } } break; case JSON_STRING: if (_pHandler) { std::size_t length = 0; const char* val = json_get_string(_pJSON, &length); _pHandler->value(std::string(val, length == 0 ? 0 : length - 1)); // Decrease the length by 1 because it also contains the terminating null character } break; case JSON_OBJECT: if (_pHandler) _pHandler->startObject(); handleObject(); break; case JSON_OBJECT_END: if (_pHandler) _pHandler->endObject(); return; case JSON_ARRAY: if (_pHandler) _pHandler->startArray(); handleArray(); break; case JSON_ARRAY_END: if (_pHandler) _pHandler->endArray(); return; case JSON_ERROR: { const char* pErr = json_get_error(_pJSON); std::string err(pErr ? pErr : "JSON parser error."); throw JSONException(err); } } }

The flow goes inside "case JSON_STRING:" and then "_pHandler->value(".

The flow comes here
`void ParseHandler::setValue(const Var& value)
{
if (_stack.size())
{
Var parent = _stack.top();

	if (parent.type() == typeid(Array::Ptr))
	{
		Array::Ptr arr = parent.extract<Array::Ptr>();
		arr->add(value);
	}
	else if (parent.type() == typeid(Object::Ptr))
	{
		Object::Ptr obj = parent.extract<Object::Ptr>();
		obj->set(_key, value);
		_key.clear();
	}
}
else throw JSONException("Attempt to set value on an empty stack");

}`

Now none of the inner if condition is passing here.

If code is changed slightly to this -
std::string parentName = parent.type().name(); std::string arrayPtrName = typeid(Array::Ptr).name(); std::string objPtrName = typeid(Object::Ptr).name(); if (parentName == arrayPtrName) { Array::Ptr arr = parent.extract<Array::Ptr>(); arr->add(value); } else if (parentName == objPtrName) { Object::Ptr obj = parent.extract<Object::Ptr>(); obj->set(_key, value, "ParseHandler::setValue"); _key.clear(); }

Then this condition is true "parentName == objPtrName". This is similar to this - #3331 (comment).

As nothing is getting saved in the map hence the while extracting issue is seen.

Digging in the std library, the type_info object comparison is something like this.

`class _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info
{
type_info& operator=(const type_info&);
type_info(const type_info&);

protected:
typedef __type_info_implementations::__impl __impl;

__impl::__type_name_t __type_name;

_LIBCPP_INLINE_VISIBILITY
explicit type_info(const char* __n)
  : __type_name(__impl::__string_to_type_name(__n)) {}

public:
_LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
virtual ~type_info();

_LIBCPP_INLINE_VISIBILITY
const char* name() const _NOEXCEPT
{
  return __impl::__type_name_to_string(__type_name);
}

_LIBCPP_INLINE_VISIBILITY
bool before(const type_info& __arg) const _NOEXCEPT
{
  return __impl::__lt(__type_name, __arg.__type_name);
}

_LIBCPP_INLINE_VISIBILITY
size_t hash_code() const _NOEXCEPT
{
  return __impl::__hash(__type_name);
}

_LIBCPP_INLINE_VISIBILITY
bool operator==(const type_info& __arg) const _NOEXCEPT
{
  return __impl::__eq(__type_name, __arg.__type_name);
}

#if _LIBCPP_STD_VER <= 17
_LIBCPP_INLINE_VISIBILITY
bool operator!=(const type_info& __arg) const _NOEXCEPT
{ return !operator==(__arg); }
#endif
};
#endif // defined(_LIBCPP_ABI_MICROSOFT)`

Maybe char* is pointing to different address and with std::string comparison is between 2 plain strings instead of char*

@matejk
Copy link
Contributor

matejk commented Jan 12, 2024

@mbhaskar98 , is it possible for you to not use the compiler flags "-fvisibility=hidden"?

Making Poco to work properly with this flag set requires more work as it seemed at first.

@mbhaskar98
Copy link
Author

mbhaskar98 commented Jan 13, 2024

  1. @matejk we are developing an iOS framework that will be used by our customers. It will contain our internal code. Without this flag all the symbols (including the private) are present in the final binary that is created. That is why want to use this flag.

  2. Also do you know why these comparisons are working correctly for x86_64 but failing for arm64 with visibility compiler flags?
    if (parent.type() == typeid(Array::Ptr)) { Array::Ptr arr = parent.extract<Array::Ptr>(); arr->add(value); } else if (parent.type() == typeid(Object::Ptr)) { Object::Ptr obj = parent.extract<Object::Ptr>(); obj->set(_key, value); _key.clear(); }

And if we change comparison to string(*.name()) then everything works fine?

  1. And what are the nature of changes from Poco to make this flag work? Is it something related to Poco code side changes or some change in build process? Or does it look like some issue with Apple's c++ std library?

@matejk
Copy link
Contributor

matejk commented Jan 13, 2024

@mbhaskar98 , please see MR #4394 for a fix for version 1.13.

Code from that MR compiles fine for iPhone using the configure and make commands that you used (Apple clang version 15.0.0).

@matejk matejk added this to the Release 1.13.1 milestone Jan 13, 2024
@matejk matejk self-assigned this Jan 13, 2024
@mbhaskar98
Copy link
Author

mbhaskar98 commented Jan 13, 2024

Thansk @matejk, these changes are working now.

Could you please explain in brief why this was working for x86_64 and not for arm64 arch ?

@matejk
Copy link
Contributor

matejk commented Jan 13, 2024

I don't know. It shouldn't work on x86_64 either.

matejk added a commit that referenced this issue Jan 13, 2024
matejk added a commit that referenced this issue Jan 13, 2024
…::column template functions only for supported types. (-fvisibility=hidden) (#4393, #3331)
matejk added a commit that referenced this issue Jan 14, 2024
…::column template functions only for supported types. (-fvisibility=hidden) (#4393, #3331)
matejk added a commit that referenced this issue Jan 15, 2024
matejk added a commit that referenced this issue Jan 17, 2024
…erly (#4394)

* fix(ActiveRecord): missing ActiveRecordLib_API definitions for clang/gcc.

* fix(FPEnvironment): export FPEnvironmentImpl classes (#4393, #3331)

* fix(Crypto): export *Impl classes used from inlines (#4393, #3331)

* fix(Dynamic): explicitly instantiate and export Dynamic::Struct for string and int (-fvisibility=hidden) (#4393, #3331)

* fix(JSON): explicitly instantiate and export SharedPtr for JSON::Array and JSON::Object (-fvisibility=hidden) (#4393, #3331)

* enh(CMake): Set symbol visibility to hidden (#4393, #3331)

* enh(configure): user c++17 standard for iphone, Darwin and ARM-Linux.

* fix(UTF): explicitly instantiate and export 16 and 32-bit strings (-fvisibility=hidden) (#4393, #3331)

* fix(RecordSet): make Extraction.h internal and instantiate RecordsSet::column template functions only for supported types. (-fvisibility=hidden) (#4393, #3331)

* fix(UTF): fix explicitly instantiation on Windows (-fvisibility=hidden) (#4393, #3331)

* enh(CMake): Add github jobs for macOS with visibility set to hidden (#4393, #3331)

* fix(CppParser): Add missing declarations for CppParser_API (#4393, #3331)

* enh(CMake): Enable more options in github jobs for macOS with visibility set to hidden (#4393, #3331)

* fix(MongoDB): Add missing MongoDB_API (#4393, #3331)
@matejk matejk added the fixed label Jan 17, 2024
@matejk matejk reopened this Jan 17, 2024
matejk added a commit that referenced this issue Jan 17, 2024
…erly (#4394)

* fix(ActiveRecord): missing ActiveRecordLib_API definitions for clang/gcc.

* fix(FPEnvironment): export FPEnvironmentImpl classes (#4393, #3331)

* fix(Crypto): export *Impl classes used from inlines (#4393, #3331)

* fix(Dynamic): explicitly instantiate and export Dynamic::Struct for string and int (-fvisibility=hidden) (#4393, #3331)

* fix(JSON): explicitly instantiate and export SharedPtr for JSON::Array and JSON::Object (-fvisibility=hidden) (#4393, #3331)

* enh(CMake): Set symbol visibility to hidden (#4393, #3331)

* enh(configure): user c++17 standard for iphone, Darwin and ARM-Linux.

* fix(UTF): explicitly instantiate and export 16 and 32-bit strings (-fvisibility=hidden) (#4393, #3331)

* fix(RecordSet): make Extraction.h internal and instantiate RecordsSet::column template functions only for supported types. (-fvisibility=hidden) (#4393, #3331)

* fix(UTF): fix explicitly instantiation on Windows (-fvisibility=hidden) (#4393, #3331)

* enh(CMake): Add github jobs for macOS with visibility set to hidden (#4393, #3331)

* fix(CppParser): Add missing declarations for CppParser_API (#4393, #3331)

* enh(CMake): Enable more options in github jobs for macOS with visibility set to hidden (#4393, #3331)

* fix(MongoDB): Add missing MongoDB_API (#4393, #3331)
@aleks-f aleks-f closed this as completed Feb 5, 2024
aleks-f added a commit that referenced this issue Feb 6, 2024
* doc(ReleaseNotes): fix formatting, add PR links

* Incorporated Debian patches (#4380)

* Debian: Use null as device file as console might not be there

* Debian: Add GNU Hurd support

* Debian: Includes not available on Hurd

* Debian: Disable SHA2 test on platforms where it's broken

* Debian: Set POCO_NO_FPENVIRONMENT for armel

---------

Co-authored-by: Jochen Sprickerhof <git@jochen.sprickerhof.de>

* fix(UUID): UUID parser silently ignores too long strings #4375 (#4384)

* fix(Crypto): EVP_CIPHER_CTX_init is incorrectly defined in Envelope.cpp if it is not defined already by OpenSSL. Fixed to properly use EVP_CIPHER_CTX_reset.

* enh(ci): Add macos sanitizers job (#4313)

* enh(ci): macOS thread sanitizer

* enh(ci): macOS sanitize jobs for undefined and address.

* fix(test): lock std:cerr to prevent data race in TCP server tests (reported by clang thread sanitizer) #4313

* fix(test): Use 96-bit IV with aes-256-gcm to fix (#4347):

I/O error: error:1C800066:Provider routines::cipher operation failed

* mingw compile and link improvements (#4019) (#4391)

* fix(platform): MinGW Compile and link errors: undefined reference to `WinMain'

* fix(platform): MinGW compile UUID tests (conflicting UUID defined as GUID in rpcdce.h via windows.h)

* enh(DateTimeParser): option to cleanup input string before parsing (#569).

* fix(CppUnit): do not install #4398

* fix(DataTest): do not install #4398

* chore(SingleSocketPoller): spelling

* fix(MailMessage): Compare lowercase content disposition headers when reading parts (#3650).

* chore(cmake): CppUnit Foundation dependency documentation; fix indentation

* fix(SocketReactorTest): deadlock test intermittently hangs #4400

* gcc/clang (-fvisibility=hidden): corrections to compile and work properly (#4394)

* fix(ActiveRecord): missing ActiveRecordLib_API definitions for clang/gcc.

* fix(FPEnvironment): export FPEnvironmentImpl classes (#4393, #3331)

* fix(Crypto): export *Impl classes used from inlines (#4393, #3331)

* fix(Dynamic): explicitly instantiate and export Dynamic::Struct for string and int (-fvisibility=hidden) (#4393, #3331)

* fix(JSON): explicitly instantiate and export SharedPtr for JSON::Array and JSON::Object (-fvisibility=hidden) (#4393, #3331)

* enh(CMake): Set symbol visibility to hidden (#4393, #3331)

* enh(configure): user c++17 standard for iphone, Darwin and ARM-Linux.

* fix(UTF): explicitly instantiate and export 16 and 32-bit strings (-fvisibility=hidden) (#4393, #3331)

* fix(RecordSet): make Extraction.h internal and instantiate RecordsSet::column template functions only for supported types. (-fvisibility=hidden) (#4393, #3331)

* fix(UTF): fix explicitly instantiation on Windows (-fvisibility=hidden) (#4393, #3331)

* enh(CMake): Add github jobs for macOS with visibility set to hidden (#4393, #3331)

* fix(CppParser): Add missing declarations for CppParser_API (#4393, #3331)

* enh(CMake): Enable more options in github jobs for macOS with visibility set to hidden (#4393, #3331)

* fix(MongoDB): Add missing MongoDB_API (#4393, #3331)

* Implemented automated network library initialization for Windows MinGW targets (#4402)

* Implemented automated network library initialization for Windows MinGW/GCC targets

* Using POCO_COMPILER_MINGW instead of __GNUC__

---------

Co-authored-by: Jesse Hoogervorst <jesse@deltaxlab.com>

* fix(Thread_POSIX): qnx build error: 'prctl' was not declared in this scope #4404

* fix: NULL pointer strategy when setting rotation never #4411

Regression from 66e93f9.

* fix(progen): add LanguageStandard (stdcpp17, stdc11); regenerate vs170 projects

* Implement GetAdaptersAddresses API (#4419)

* Upgrade from GetAdaptersInfo to GetAdaptersAddresses API. The code has been swapped back to a buffer of bytes because the data structure built by GetAdaptersAddresses is a linked list and the returned size is not a multiple of the IP_ADAPTERS_ADDRESSES struct.

* Adding back Poco/UnWindows.h

* Undoing indents.

* test(ThreadPool): unit test for thread pool shutdown when no worker is running. (#2450)

* enh: #4216: use std::string literals

* enh: #3890: Get rid of SingletonHolder

* enh(File): Linux, macOS: microsecond precision for file times (create and modification time).

* enh(tests): Ability to enable/disable testing of deprecated functionality. (#4425)

* fix(SSLManager): Fixed regression introduced in PR #4103, fixes #4421

* fix(LogFile): Unify flushing behaviour of WIN32 and STD implementation (#2443)

* chore(buildwin): remove old vs versions from build and progen scripts; update documentation

* chore(buildwin): remove leftover closing curly

* enh(SQLite): SQLite FTS5 #4367

* Release 1.13.1: Update release notes, changelog, contributors, version files. (#4440)

* Update CONTRIBUTORS

* fix(CppParser): Documentation generation (some minor fixes, WiP) #4441

* feat(CppParser): C++11 attributes support

* feat(PocoDoc): C++11 attributes support

* chore(doc): Changelog and release notes formatting

* fix(CppParser): parsing of function template parameters and namespace imports

* fix: make headers parseable by CppParser/PocoDoc

* fix(PocoDoc): add -DPOCO_DOC

* fix(PocoDoc): postgres headers not found

* fix(PocoDoc): libpq include path

* fix(XML): #4443: Upgrade libexpat to 2.6.0

* doc: updated changelog

---------

Co-authored-by: Günter Obiltschnig <guenter.obiltschnig@appinf.com>
Co-authored-by: Matej Kenda <matejken@gmail.com>
Co-authored-by: Jochen Sprickerhof <git@jochen.sprickerhof.de>
Co-authored-by: Jesse Hoogervorst <hoogervorstjesse@gmail.com>
Co-authored-by: Jesse Hoogervorst <jesse@deltaxlab.com>
Co-authored-by: Aron Budea <aron.budea@collabora.com>
Co-authored-by: Andrew Auclair <andrewauclair@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants