I am reading in a serialized class from memory using Boost 1.41 and am getting an "unsupported version" exception even though the program that produced the serialized class also used Boost 1.41.
I'm using the following method to read the data:
void ConvertMessage (const unsigned char *msgAddress)
{
MessageData messageData;
int msgSize = msgSystem.getDataSize (message); // external system returns message size
char *msgData = new char[msgSize];
memcpy (msgData, msgAddress, msgSize);
try
{
typedef boost::iostreams::basic_array_source<char> Device;
boost::iostreams::stream_buffer<Device> msgStream (msgData, msgSize);
boost::archive::binary_iarchive msg (msgStream); // exception thrown here
msg >> messageData;
}
catch (boost::archive::archive_exception const &e)
{
cout << e.what() << endl;
}
// Code to convert messageData to an internal class.
}
I've read that there was an issue with reading archives from pre-Boost 1.44 with Boost 1.44 but I'm seeing the issue with both sides using Boost 1.41.
I was able to run this without an issue when the two programs were using the same libraries as we were on the same computer but now we are on separate computers.
Is there some way to verify that we are actually using the exact same versions?
I'm assuming that if the producer of the serialization is using Boost 1.41 and I'm using Boost 1.41 to deserialize the data there shouldn't be an issue, but I'm seeing the "unsupported version" exception when I try to create the boost::archive::binary_iarchive.
It turns out that the program that was building the stream in memory was using Boost 1.54 so that would explain the reason for the "unsupported version" exception.
I'm now linking to the same library and it is working fine.
Related
I have a program using cpprestsdk for http querying and websocketpp for subscribing a data stream. The program will crash immediately(it says Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)). But if I comment either of the http querying or subcribing data stream, the program won't crash.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include "json.hpp"
#include <iostream>
#include <ctime>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <vector>
#include <string>
using std::string;
using namespace web;
using std::cout, std::endl;
using std::vector;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_stream_data(websocketpp::connection_hdl hdl, message_ptr msg) {
}
class OrderBook {
public:
void initialize() {
web::http::client::http_client_config cfg;
std::string uri = string("https://fapi.binance.com/fapi/v1/depth?symbol=btcusdt&limit=1000");
web::http::client::http_client client(U(uri), cfg);
web::http::http_request request(web::http::methods::GET);
request.headers().add("Content-Type", "application/x-www-form-urlencoded");
web::http::http_response response = client.request(request).get();
}
int start_stream() {
client c;
std::string uri = string("wss://fstream.binance.com/ws/btcusdt#depth#100ms");
try {
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.init_asio();
c.set_message_handler(bind(on_stream_data, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
};
int main(int argc, char *argv[]) {
OrderBook ob;
ob.initialize(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
std::this_thread::sleep_for(std::chrono::milliseconds(10000000));
ob.start_stream(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
}
When I run this program in Clion debug mode, Clion show that the crash comes from function in /opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/ssl/detail/impl/engine.ipp
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
It says Exception: EXC_BAD_ACCESS (code=1, address=0xf000000000)
What's wrong with it? is it because I run two pieces of code using boost::asio, and something shouldn't be initialized twice?
I can compile this and run it fine.
My best bet is that you might be mixing versions, particularly boost versions. A common mode of failure is caused when ODR violations lead to Undefined Behaviour.
Note that these header-only libraries depend on a number of boost libraries that are not header-only (e.g. Boost System, Thread and/or Chrono). You need to compile against the same version as the libraries you link.
If you use distribution packaged versions of any library (cpprestsdk, websocketpp or whatever json library that is you're using) then you'd be safest also using the distribution packaged version of Boost.
I'd personally simplify the situation by just using Boost (Beast for HTTP/websocket, Json for, you guessed it).
Running it all on a test Ubuntu 18.04 the OS Boost 1.65 version, the start_stream sequence triggers this informative error:
[2022-05-22 13:42:11] [fatal] Required tls_init handler not present.
could not create connection because: Connection creation attempt failed
While being UBSAN/ASAN clean. Perhaps that error helps you, once you figure out the configuration problems that made your program crash.
I try to make youtube subscribe counter but it a problem with youtube api library here the error message
Arduino: 1.8.12 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"
The sketch name had to be modified.
Sketch names must start with a letter or number, followed by letters,
numbers, dashes, dots and underscores. Maximum length is 63 characters.
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp:95:11: error: DynamicJsonBuffer is a class from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6
DynamicJsonBuffer jsonBuffer;
^
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp: In member function 'bool YoutubeApi::getChannelStatistics(String)':
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp:95:20: error: 'jsonBuffer' was not declared in this scope
DynamicJsonBuffer jsonBuffer;
^
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp:97:10: error: 'ArduinoJson::JsonObject' has no member named 'success'
if(root.success()) {
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
Invalid library found in C:\Program Files (x86)\Arduino\libraries\libraries: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\libraries
Invalid library found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino
Invalid library found in C:\Program Files (x86)\Arduino\libraries\libraries: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\libraries
Invalid library found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I already download youtube api library and arduino json library and import it to arduino ide I always get error from it i dont know why it gone like this someone who know please help me. I like to hear from you.
And here my code :
/*******************************************************************
* Read YouTube Channel statistics from the YouTube API *
* *
* By Brian Lough *
* https://www.youtube.com/channel/UCezJOfu7OtqGzd5xrP3q6WA *
*******************************************************************/
#include <YoutubeApi.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h> // This Sketch doesn't technically need this, but the library does so it must be installed.
//------- Replace the following! ------
char ssid[] = "xxx"; // your network SSID (name)
char password[] = "yyyy"; // your network key
#define API_KEY "zzzz" // your google apps API Token
#define CHANNEL_ID "UCezJOfu7OtqGzd5xrP3q6WA" // makes up the url of channel
WiFiClientSecure client;
YoutubeApi api(API_KEY, client);
unsigned long api_mtbs = 60000; //mean time between api requests
unsigned long api_lasttime; //last time api request has been done
long subs = 0;
void setup() {
Serial.begin(115200);
// Set WiFi to station mode and disconnect from an AP if it was Previously
// connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
// Attempt to connect to Wifi network:
Serial.print("Connecting Wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
IPAddress ip = WiFi.localIP();
Serial.println(ip);
}
void loop() {
if (millis() - api_lasttime > api_mtbs) {
if(api.getChannelStatistics(CHANNEL_ID))
{
Serial.println("---------Stats---------");
Serial.print("Subscriber Count: ");
Serial.println(api.channelStats.subscriberCount);
Serial.print("View Count: ");
Serial.println(api.channelStats.viewCount);
Serial.print("Comment Count: ");
Serial.println(api.channelStats.commentCount);
Serial.print("Video Count: ");
Serial.println(api.channelStats.videoCount);
// Probably not needed :)
//Serial.print("hiddenSubscriberCount: ");
//Serial.println(api.channelStats.hiddenSubscriberCount);
Serial.println("------------------------");
}
api_lasttime = millis();
}
}
I would ditch the libraray - it uses
#include <ArduinoJson.h>
and the error tells us whats wrong
error: DynamicJsonBuffer is a class from ArduinoJson 5 <=== you have probably version 6.x.x installed
which is a memory hog. Often one single function is used by libraries and the rest is useless. To solve your problem, you have to
downgrade ArduinoJson.h to version 5.13.5
The other reason I do not like it, breaking changes in nearly all major releases (real big breaking). So another option you have (if skilled enough) replace the ArduinoJson functions with
a lighter JSON library
or replace it with self written JSON functions - often a simple buffer and some char handling does the trick
Read the issues and PRs on github to inform yourself about missing updates and other problems. Development stopped March 2018 since then no adaption to the (breaking) changes in the youtube API
Because of ASLR(Address space layout randomization, since Windows Vista), the base address of an exe is random, so it can't be found in PE file anymore.
In Visual C++ now the /DYNAMICBASE option is default enabled, so the base address
of an exe is random - everytime the loader loads it, it happens.
After did some research on google, I am trying to use this pattern,
But it doesn't work.
Please have a look at this simple code sample:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
int main()
{
STARTUPINFOA startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInformation = {0};
if (CreateProcessA("UseCase01.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))
{
std::vector<HMODULE> buf(128);
DWORD needed = 0;
for (;;) {
if (EnumProcessModulesEx(processInformation.hProcess, &buf[0], DWORD(buf.size()*sizeof(HMODULE)), &needed, LIST_MODULES_ALL) == FALSE) {
DWORD ec = GetLastError();
std::cout << ec << std::endl;
break;
}
else if (needed <= buf.size() * sizeof(HMODULE)) {
break;
}
else {
const size_t oldSize = buf.size();
buf.resize(oldSize * 2);
}
}
ResumeThread(processInformation.hThread);
}
}
My OS is Windows 7 64bit pro, my compiler is VS2013, this is a 32bit console program, and the UseCase01.exe is also a 32bit console program too.
EnumProcessModulesEx always fails, the error code returned by GetLastError() is 299, MSDN says what about this error code: ERROR_PARTIAL_COPY, "Only part of a ReadProcessMemory or WriteProcessMemory request was completed."
About this error code, on the EnumProcessModules's page of MSDN, "If this function is called from a 32-bit application running on WOW64, it can only enumerate the modules of a 32-bit process. If the process is a 64-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299)."
But I am sure my program is 32bit, And, I tested on 64bit program, it fails with error 299 too, so it doesn't make sence.
"The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object." - from MSDN, so it can't be a access rights problem ?
Then I try to use CreateToolhelp32Snapshot, it fails with error code 299 too, both 32bit and 64bit.
I just can't figure it out.
My goal is find the entry point of the sub-process in a safe way, whatever it's 32bit or 64bit process.
I found this is the "deepest" answer about this question: http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
Unfortunately, 64bit program will fails too, not only for Wow64, so it doesn't make sence.
If this is infeasible, what is the good way (find base address or entry point of a suspended sub-process)?
You are creating the process suspended. While the key kernel data structures will be created, no modules will be loaded (that would involve executing code in module entry points (dllmain)).
Thus the error makes sense: the data structures to track modules loaded will be empty, and quite possibly not allocated at all.
Put some wait it will help you it looks currently resource is not available.
On all Windows operating systems (32/64bit):
DWORD ImageBaseAddress = ((LPDWORD)PEB)[2]
I have troubles with dynamic loading of libraries - my code panics with Kern-Exec 3. The code is as follows:
TFileName dllName = _L("mydll.dll");
TFileName dllPath = _L("c:\\sys\\bin\\");
RLibrary dll;
TInt res = dll.Load(dllName, dllPath); // Kern-Exec 3!
TLibraryFunction f = dll.Lookup(1);
if (f)
f();
I receive panic on TInt res = dll.Load(dllName, dllPath); What can I do to get rid of this panic? mydll.dll is really my dll, which has only 1 exported function (for test purposes). Maybe something wrong with the DLL? Here's what it is:
def file:
EXPORTS
_ZN4Init4InitEv # 1 NONAME
pkg file:
#{"mydll DLL"},(0xED3F400D),1,0,0
;Localised Vendor name
%{"Vendor-EN"}
;Unique Vendor name
:"Vendor"
"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\mydll.dll"-"!:\sys\bin\mydll.dll"
mmp file:
TARGET mydll.dll
TARGETTYPE dll
UID 0x1000008d 0xED3F400D
USERINCLUDE ..\inc
SYSTEMINCLUDE \epoc32\include
SOURCEPATH ..\src
SOURCE mydllDllMain.cpp
LIBRARY euser.lib
#ifdef ENABLE_ABIV2_MODE
DEBUGGABLE_UDEBONLY
#endif
EPOCALLOWDLLDATA
CAPABILITY CommDD LocalServices Location MultimediaDD NetworkControl NetworkServices PowerMgmt ProtServ ReadDeviceData ReadUserData SurroundingsDD SwEvent TrustedUI UserEnvironment WriteDeviceData WriteUserData
source code:
// Exported Functions
namespace Init
{
EXPORT_C TInt Init()
{
// no implementation required
return 0;
}
}
header file:
#ifndef __MYDLL_H__
#define __MYDLL_H__
// Include Files
namespace Init
{
IMPORT_C TInt Init();
}
#endif // __MYDLL_H__
I have no ideas about this... Any help is greatly appreciated.
P.S. I'm trying to do RLibrary::Load because I have troubles with static linkage. When I do static linkage, my main program doesn't start at all. I decided to check what happens and discovered this issue with RLibrary::Load.
A KERN-EXEC 3 panic is caused by an unhandled exception (CPU fault) generated by trying to invalidly access a region of memory. This invalid memory access can be for both code (for example, bad PC by stack corruption) or data (for example, accessing freed memory). As such these are typically observed when dereferencing a NULL pointer (it is equivalent to a segfault).
Certainly the call to RLibrary::Load should never raise a KERN-EXEC 3 due to programmatic error, it is likely to be an environmental issue. As such I have to speculate on what is happening.
I believe the issue that is observed is due to stack overflow. Your MMP file does not specify the stack or heap size the initial thread should use. As such the default of 4Kb (if I remember correctly) will be used. Equally you are using TFileName - use of these on the stack is generally not recommended to avoid... stack overflow.
You would be better off using the _LIT() macro instead - this will allow you to provide the RLibrary::Load function with a descriptor directly referencing the constant strings as located in the constant data section of the binary.
As a side note, you should check the error value to determine the success of the function call.
_LIT(KMyDllName, "mydll.dll");
_LIT(KMyDllPath, "c:\\sys\\bin\\");
RLibrary dll;
TInt res = dll.Load(KMyDllName, MyDllPath); // Hopefully no Kern-Exec 3!
if(err == KErrNone)
{
TLibraryFunction f = dll.Lookup(1);
if (f)
f();
}
// else handle error
The case that you can't use static linkage should be a strong warning to you. It shows that there is something wrong with your DLL and using dynamic linking won't change anything.
Usually in these cases the problem is in mismatched capabilities. DLL must have at least the same set of capabilities that your main program has. And all those capabilities should be covered by your developer cert.
My program:
typedef struct objc_class {
struct objc_class *isa;
struct objc_class *super_class;
char *name;
long version;
long info;
long instance_size;
void *ivars;
void *methodLists;
void *cache;
void *protocols;
} *Class;
struct objc_object {
Class isa;
};
/* Code to extract the class name from arg0 based on a snippet by Bill Bumgarner: http://friday.com/bbum/2008/01/26/objective-c-printing-class-name-from-dtrace/ */
objc$target:NSObject:-init:entry {
printf("time: %llu\n", timestamp);
printf("arg0: %p\n", arg0);
obj = (struct objc_object *)copyin(arg0, sizeof(struct objc_object));
printf("obj: %p\n", obj);
printf("obj->isa: %p\n", obj->isa);
isa = (Class)copyin((user_addr_t)obj->isa, sizeof(struct objc_class));
printf("isa: %p\n", obj->isa);
classname = copyinstr((user_addr_t)(isa->name));
printf("classname: %s\n", classname);
}
Some output:
dtrace: script 'test.d' matched 1 probe
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
CPU ID FUNCTION:NAME
0 61630 -init:entry time: 28391086668386
arg0: 1291ae10
obj: 6f0a1158
obj->isa: a023f360
isa: a023f360
classname: NSBitmapImageRep
1 61630 -init:entry time: 28391586872297
arg0: 12943560
obj: 6f4a1158
obj->isa: 2fca0
isa: 2fca0
classname: GrowlApplicationTicket
1 61630 -init:entry time: 28391586897807
arg0: 152060
obj: 6f4a1280
obj->isa: 2fe20
isa: 2fe20
classname: GrowlNotificationTicket
2 61630 -init:entry time: 28391079142905
arg0: 129482d0
obj: 700a1128
obj->isa: a0014140
isa: a0014140
classname: NSDistributedObjectsStatistics
2 61630 -init:entry time: 28391079252640
arg0: 147840
obj: 700a1250
obj->isa: a0014780
isa: a0014780
classname: NSDistantObjectTableEntry
Why the errors? It seems to be the class name (that's the only %s, and I don't get any errors if I remove it), but why does it think some classes' names are invalid pointers?
Is there any way to get the error messages to actually tell me which line of my DTrace program caused a problem?
Is there a way to call object_getClassName instead of doing this structure-inspection dance?
For what it's worth, the program I'm tracing works fineāit's not crashing, so I don't believe that the classes really are broken.
Colin is pretty close to correct.
See:
http://www.friday.com/bbum/2008/01/03/objective-c-using-dtrace-to-trace-messages-to-nil/
More likely than not, you need to set the DYLD_SHARED_REGION environment variable to avoid. dtrace only really works against mapped memory that is actually resident in physical memory.
You can figure out what is missing by using the vmmap command line tool.
Do a vmmap PID on your application after the above failure messages are generated. Looking at the output, see what region the addresses like 0x90206b98 fall into. Given that address, it is likely in a non-writeable shared chunk of memory that probably isn't resident and, thus, dtrace can't read from it.
This error happens when copyin / copyinstr is used on a page that's not faulted in yet. A common workaround is to let the function use the data in question, and then copyin[str] in a :::return clause. For example:
syscall::open:entry
{
self->filename = arg0; /* Hang on to the file name pointer. */
}
syscall::open:return
/self->filename/
{
#files[copyinstr(self->filename)] = count();
self->filename = 0;
}
END
{
trunc(#files, 5);
}
I haven't entirely tracked this down myself. It's possible that DTrace is trying to resolve some Objective-C symbols. Although DTrace is a dynamic tracing facility it doesn't mesh well with Objective-C dynamically loading things at runtime. When Objective-C does load new classes,etc DTrace has to resolve this and it takes a little time, especially when your app is just starting up. Even if it does get things loaded, and your objc app is still loading new classes onto the objc runtime its possible DTrace could get screwed up and print methods in the wrong order (if you care about seeing the correct order methods are being executed in), print incorrect timing results,etc.
This is my best guess based on the information provided.
DTrace was purposefully designed in such a way as to make DTrace scripts as deterministic as possible. This is why there are no if statements, loops, subroutines (other than the pseudo-subroutines provided by DTrace itself), etc. This is because the code in your DTrace script is running in kernel mode, not user-land as part of the process(es) being traced. In general, the information DTrace has access to is "read-only" (like most generalizations, this is not strictly true), being able to twiddle bits in programs, or the kernel, with something as powerful as DTrace can cause things to go very, very wrong, very very quickly.
Dollars to donuts, the problem you're having is because the page that the pointer points to is not mapped in to core by the VM system. DTrace can only examine information for memory that is in core- it can't double-fault to get the VM system to load in the page.
You can probably help alleviate the problem if you've got an idea of what the classes "should" be and forcing the pages to be mapped in to core by doing a bunch of dummy NSLog() statements that reference the needed classes at some convenient point early in your programs start up.