Field '__jmpbuf' could not be resolved -cpp - c++

I get this error when trying to compile my program:
Field '__jmpbuf' could not be resolved
I looked for a solution for hours and can't seem to find out where is the culprit.
The Thread.h file contains the header of the class. It has the private member:
sigjmp_buf _env;
And the implementation is inside Thread.cpp:
#include "Thread.h"
#include <setjmp.h>
#include "translateAdd.h"
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#define COUNTER_INIT -1
int Thread::_idCounter = COUNTER_INIT;
Thread::Thread(void (*threadsFunc)(void))
: threadsFunction(threadsFunc), _stack(new char[STACK_SIZE]), _quantums(1)
{
address_t sp, pc;
sp = (address_t)_stack + STACK_SIZE - sizeof(address_t);
pc = (address_t)threadsFunc;
// set environment for later return
sigsetjmp(_env, 1);
(_env->__jmpbuf)[JB_SP] = translate_address(sp);
(_env->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&_env->__saved_mask);
_id = ++_idCounter;
_state = READY;
}
EDIT: Using eclipse as the IDE under ubuntu 32bit
EDIT: Another complete example that doesn't compile on my machine:
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#define SECOND 1000000
#define STACK_SIZE 4096
char stack1[STACK_SIZE];
char stack2[STACK_SIZE];
sigjmp_buf env[2];
#ifdef __x86_64__
/* code for 64 bit Intel arch */
typedef unsigned long address_t;
#define JB_SP 6
#define JB_PC 7
/* A translation is required when using an address of a variable.
Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%fs:0x30,%0\n"
"rol $0x11,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
#else
/* code for 32 bit Intel arch */
typedef unsigned int address_t;
#define JB_SP 4
#define JB_PC 5
/* A translation is required when using an address of a variable.
Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%gs:0x18,%0\n"
"rol $0x9,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
#endif
void switchThreads(void)
{
static int currentThread = 0;
int ret_val = sigsetjmp(env[currentThread],1);
printf("SWITCH: ret_val=%d\n", ret_val);
if (ret_val == 1) {
return;
}
currentThread = 1 - currentThread;
siglongjmp(env[currentThread],1);
}
void f(void)
{
int i = 0;
while(1){
++i;
printf("in f (%d)\n",i);
if (i % 3 == 0) {
printf("f: switching\n");
switchThreads();
}
usleep(SECOND);
}
}
void g(void)
{
int i = 0;
while(1){
++i;
printf("in g (%d)\n",i);
if (i % 5 == 0) {
printf("g: switching\n");
switchThreads();
}
usleep(SECOND);
}
}
void setup(void)
{
address_t sp, pc;
sp = (address_t)stack1 + STACK_SIZE - sizeof(address_t);
pc = (address_t)f;
sigsetjmp(env[0], 1);
(env[0]->__jmpbuf)[JB_SP] = translate_address(sp);
(env[0]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env[0]->__saved_mask);
sp = (address_t)stack2 + STACK_SIZE - sizeof(address_t);
pc = (address_t)g;
sigsetjmp(env[1], 1);
(env[1]->__jmpbuf)[JB_SP] = translate_address(sp);
(env[1]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env[1]->__saved_mask);
}
int main(void)
{
setup();
siglongjmp(env[0], 1);
return 0;
}

If you really need to use the internal fields (which will only be valid for your compiler on your system) you need to check the types:
typedef struct __jmp_buf_tag sigjmp_buf[1];
That means that sigjmp_buf is not a pointer, but an array with a single structure in it. So you use it like a normal array of structures:
sigjmp_buf _env;
_env[0].__jmpbuf[x] = y;
I really recommend against the use the internal field of this structure. Linux have other functions to simplify cooperative threading (which is what you seem to be implementing).

Related

Memory management code crashing

I am making a GTA 5 mod using Scripthook. I ran their sample code with no issues, but when I try and make my own, it crashes the game.
#include "script.h"
#include "keyboard.h"
#include <string>
#include <ctime>
#pragma warning(disable : 4244 4305) // double <-> float conversions
#define ID 0
#define PED 1
LPINT currentPlayer() {
LPINT ret = (LPINT)malloc(sizeof(int) * 2);
ret[0] = PLAYER::PLAYER_ID();
ret[1] = PLAYER::PLAYER_PED_ID();
return ret;
}
void getPlayerCoords(LPVOID coords) {
*(Vector3 *)coords = ENTITY::GET_ENTITY_COORDS(currentPlayer()[PED], true);
}
void spawnKuruma2() {
Vector3 *currentCoordinates = (Vector3 *)malloc(sizeof(Vector3));
getPlayerCoords(currentCoordinates);
Hash kHash = GAMEPLAY::GET_HASH_KEY("KURUMA2");
STREAMING::REQUEST_MODEL(kHash);
while (!STREAMING::HAS_MODEL_LOADED(kHash));
Vehicle kuruma2 = VEHICLE::CREATE_VEHICLE(kHash, (*currentCoordinates).x + 5.0, (*currentCoordinates).y + 5.0, (*currentCoordinates).z, 0.0, true, true);
VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(kuruma2);
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(kHash);
ENTITY::SET_VEHICLE_AS_NO_LONGER_NEEDED(&kuruma2);
}
void main()
{
while (1)
{
if (IsKeyJustUp(VK_F8))
{
spawnKuruma2();
}
WAIT(0);
}
}
void ScriptMain()
{
srand(GetTickCount());
main();
}
I'm positive that it has something to do with the malloc call, but it looks fine to me. Can anyone point out what I could be doing wrong?

HTTPS with openssl on linux in C/C++

I have a project where I need to create a secure http server in C/C++ on Linux and I've chosen to use openssl, however, when I try to include the applinker.c from their github I see a lot of errors, mostly because the file seems to be written for Windows.I would like to know if there is an alternative for Linux or how should I deal with this.
Here is the applinker.c code:
/*
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#define APPLINK_STDIN 1
#define APPLINK_STDOUT 2
#define APPLINK_STDERR 3
#define APPLINK_FPRINTF 4
#define APPLINK_FGETS 5
#define APPLINK_FREAD 6
#define APPLINK_FWRITE 7
#define APPLINK_FSETMOD 8
#define APPLINK_FEOF 9
#define APPLINK_FCLOSE 10 /* should not be used */
#define APPLINK_FOPEN 11 /* solely for completeness */
#define APPLINK_FSEEK 12
#define APPLINK_FTELL 13
#define APPLINK_FFLUSH 14
#define APPLINK_FERROR 15
#define APPLINK_CLEARERR 16
#define APPLINK_FILENO 17 /* to be used with below */
#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */
#define APPLINK_READ 19
#define APPLINK_WRITE 20
#define APPLINK_LSEEK 21
#define APPLINK_CLOSE 22
#define APPLINK_MAX 22 /* always same as last macro */
#ifndef APPMACROS_ONLY
# include <stdio.h>
# include <io.h>
# include <fcntl.h>
static void *app_stdin(void)
{
return stdin;
}
static void *app_stdout(void)
{
return stdout;
}
static void *app_stderr(void)
{
return stderr;
}
static int app_feof(FILE *fp)
{
return feof(fp);
}
static int app_ferror(FILE *fp)
{
return ferror(fp);
}
static void app_clearerr(FILE *fp)
{
clearerr(fp);
}
static int app_fileno(FILE *fp)
{
return _fileno(fp);
}
static int app_fsetmod(FILE *fp, char mod)
{
return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport)
void **
# if defined(__BORLANDC__)
/*
* __stdcall appears to be the only way to get the name
* decoration right with Borland C. Otherwise it works
* purely incidentally, as we pass no parameters.
*/
__stdcall
# else
__cdecl
# endif
OPENSSL_Applink(void)
{
static int once = 1;
static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] =
{ (void *)APPLINK_MAX };
if (once) {
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
OPENSSL_ApplinkTable[APPLINK_READ] = _read;
OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
once = 0;
}
return OPENSSL_ApplinkTable;
}
#ifdef __cplusplus
}
#endif
#endif
And here is a little snippet I prepared for testing the connection:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <arpa/inet.h>
#include <cstdio>
#include <sys/stat.h>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <fstream>
#include <thread>
#include "openssl-master/ms/applink.c"
#include "openssl-master/include/openssl/bio.h"
#include "openssl-master/include/openssl/ssl.h"
#include "openssl-master/include/openssl/err.h"
#define PORT 2024
void InitializeSSL()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void DestroySSL()
{
ERR_free_strings();
EVP_cleanup();
}
void ShutdownSSL(SSL *ssl)
{
SSL_shutdown(ssl);
SSL_free(ssl);
}
int main(int argc, const char * argv[]) {
int sockfd, newsockfd;
SSL_CTX *sslctx;
SSL *cSSL;
InitializeSSL();
struct sockaddr_in server;
struct sockaddr_in from;
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);
int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);
int sd;
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket() error.\n");
return errno;
}
bzero (&server, sizeof (server));
bzero (&from, sizeof (from));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl (INADDR_ANY);
server.sin_port = htons (PORT);
if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
{
perror ("bind() error.\n");
return errno;
}
if (listen (sd, 5) == -1)
{
perror ("listen() error.\n");
return errno;
}
int client;
socklen_t length = sizeof (from);
printf ("Waiting on port %d...\n",PORT);
fflush (stdout);
client = accept (sd, (struct sockaddr *) &from, &length);
if (client < 0)
{
perror ("accept() error.\n");
return 0;
}
cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, client);
int ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0)
{
ShutdownSSL(cSSL);
}
return 0;
}
And I compile it like this: g++ withssl.cpp libssl.a libcrypto.a -lssl -lcrypto -o server.bin
Code looks good, I used Suse Leap 4.2.2 and performed these commands:
openssl version
OpenSSL 1.0.2j-fips 26 Sep 2016
sudo zypper in openssl-devel
g++ -std=c++11 main.cpp -lssl -lcrypto -o server
Because I am using the distro provided openssl I changed your code to include the standard headers like this:
#include <openssl/ssl.h>
#include <openssl/err.h>
// DONT NEED
// suggest instead of including C code, link to the libraries
// for example, /usr/lib64/libssl.so contains referenced functions
// observe the provided functions using a command like this
// readelf -a /usr/lib64/libssl.so | grep FUNC
// #include "openssl-master/ms/applink.c"
// WRONG PATH?
// suggest you use a distro provided openssl instead of building your own
// #include "openssl-master/include/openssl/bio.h"
// #include "openssl-master/include/openssl/ssl.h"
// #include "openssl-master/include/openssl/err.h"

Code is not working (C++ unions and structures)

No matter how many times I reformat this, I keep getting all kinds of errors. The end result will be a program that can save functions targeting motors in a telescope and set coordinates. Any help in explaining what I am doing wrong with this setup would be greatly appreciated. here is the code:
//IDENTIFY RECEIVER OF MESSAGE / TYPE OF MESSAGE / VIEW ALL TO 1 DEVICE / VIEW SPECIFIC MESSAGE
#include "messaging.h"
#include <string.h>
#include <stdio.h>
using namespace std;
typedef struct MGR{
mess_types messagetype;
int DeviceID;
union E{
//why arte these underlined?
char INST[STRSIZE];
int codes[NBRCODES];
float coords[NBRCOORDS];
} message;
};// info;
void messager(){
MGR my_data;
my_data.messagetype = INST;
my_data.DeviceID = TECH1;
strcpy(my_data.message.INST, "GO HOME");
my_data.messagetype = CODES;
my_data.DeviceID = MOTOR1;
for (int nbr = 0; nbr < NBRCODES; nbr++){
my_data.message.codes[nbr] = nbr;
print_message(my_data);
}
}
int print_message(MGR mydata){
MGR noot;
scanf("%s", &mydata);
switch (mydata.messagetype){
case INST:
printf("Message to Device %d", noot.DeviceID);
break;
case CODES:
printf("The setup codes for device %d are: \n", noot.DeviceID);
for (int code = 0; code < NBRCODES + OFFSET; code++){
printf("%4d\t", noot.message);
}
break;
case COORDS:
printf("The setup codes for device %d are: \n", noot.DeviceID);
for (int code = 0; code < NBRCODES + OFFSET; code++){
printf("%4d\t", noot.message);
}
break;
}
printf("%c", mydata.messagetype);
return(0)
}
void Sendmessage(){
printf("This program does not work... it is under construction...");
}
Just in case: here is the header file
#include "sprint1.h"
#include <string.h>
#include <stdio.h>
#define STRSIZE 50
#define NBRCODES 200
#define NBRCOORDS 200
#define OFFSET 100
#define FACTOR 50
#define TECH1 123
#define MOTOR1 4556
void messager();
int print_message(MGR mydata);
void Sendmessage();
enum mess_types {INST, CODES, COORDS};
Error list: https://drive.google.com/file/d/0B0CXbbHDOrweQVVvOVU1M0VRaEE/view?usp=sharing
I assume the header listed is "messaging.h"
MGR is referenced in the header before it's definition in the code.
Maybe move the definition to the header before the first reference.

Issue getting functions from library and strange conversion error

I'm trying to write an arduino library. I've written a few classes before but nothing for arduino. I'm running into one error pretty consistently. First let me show you the code:
Code
Main.ino (The arduino project)
#include <Wire.h>
#include "Mobility.h"
Mobility mol = new Mobility();
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
Serial.println("loop");
mol.move(true, 125, false, 125, 10);
delay(2000);
}
Mobility.h
#ifndef MOBILITY_H
#define MOBILITY_H
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
const int DEFAULT_MOBILITY_ADD = 4;
class Mobility
{
public:
void begin();
void begin(int address);
int i2cAdd;
int move(bool lPos, unsigned char leftPower, bool rPos, unsigned char rightPower, unsigned char msec);
private:
};
/**/
#endif
Mobility.cpp
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Mobility.h"
#include "Wire.h"
void Mobility::begin(){
Wire.begin();
this.i2cAdd = DEFAULT_MOBILITY_ADD;
}
void Mobility::begin(int address){
Wire.begin();
this.i2cAdd = address;
}
int Mobility::move(bool lPos, unsigned char leftPower,bool rPos, unsigned char rightPower, unsigned char msec){
if (leftPower < -255 || leftPower > 255){
return -1;
}
if (rightPower < -255 || rightPower > 255){
return -2;
}
if(msec <= 0){
return -3;
}
Wire.beginTransmission(this.i2cAdd);
Wire.write(lPos);
Wire.write(leftPower);
Wire.write(rPos);
Wire.write(rightPower);
Wire.write(msec);
Wire.endTransmission();
return 0;
}
ERRORS
I've been getting two big errors while I've been trying to fix the code. The first is:
error: conversion from 'Mobility*' to non-scalar type 'Mobility' requested
Mobility mol = new Mobility();
The problem is caused by this line:
Mobility mol = new Mobility();
the first part is static memory allocation:Mobility mol - statically allocates memory for the object mol.
the second part uses dynamic memory allocation: new - dynamically allocates memory.
So you can do :
Mobility mol;// static allocation
or
Mobility *mol = new Mobility(); //dynamic allcocation
But not a mix of the two. Either way the constructor will be called when creating the object.

How can I find out how much memory my c++ app is using on the Mac

Certain operations in my app are using more memory than I think they should, and I would like to log the current memory usage to help identify which they are.
Is there a system call that will return the amount of memory currently in use?
The following C function returns the CPU time and resident memory of process pid. To get the resources of other processes, you need root permission. You may also try getrusage(), but I never get it work properly for memory usage. Getting CPU time with getrusage() always works to me.
The function is adapted from the source codes of the ps and top commands. It is part of my program that monitors the memory of other processes.
#ifdef __APPLE__
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/mach_port.h>
#include <mach/mach_traps.h>
#include <mach/task_info.h>
#include <mach/thread_info.h>
#include <mach/thread_act.h>
#include <mach/vm_region.h>
#include <mach/vm_map.h>
#include <mach/task.h>
#include <mach/shared_memory_server.h>
typedef struct vmtotal vmtotal_t;
typedef struct { /* dynamic process information */
size_t rss, vsize;
double utime, stime;
} RunProcDyn;
/* On Mac OS X, the only way to get enough information is to become root. Pretty frustrating!*/
int run_get_dynamic_proc_info(pid_t pid, RunProcDyn *rpd)
{
task_t task;
kern_return_t error;
mach_msg_type_number_t count;
thread_array_t thread_table;
thread_basic_info_t thi;
thread_basic_info_data_t thi_data;
unsigned table_size;
struct task_basic_info ti;
error = task_for_pid(mach_task_self(), pid, &task);
if (error != KERN_SUCCESS) {
/* fprintf(stderr, "++ Probably you have to set suid or become root.\n"); */
rpd->rss = rpd->vsize = 0;
rpd->utime = rpd->stime = 0;
return 0;
}
count = TASK_BASIC_INFO_COUNT;
error = task_info(task, TASK_BASIC_INFO, (task_info_t)&ti, &count);
assert(error == KERN_SUCCESS);
{ /* adapted from ps/tasks.c */
vm_region_basic_info_data_64_t b_info;
vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT;
vm_size_t size;
mach_port_t object_name;
count = VM_REGION_BASIC_INFO_COUNT_64;
error = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO,
(vm_region_info_t)&b_info, &count, &object_name);
if (error == KERN_SUCCESS) {
if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) &&
ti.virtual_size > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE))
{
ti.virtual_size -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
}
}
rpd->rss = ti.resident_size;
rpd->vsize = ti.virtual_size;
}
{ /* calculate CPU times, adapted from top/libtop.c */
unsigned i;
rpd->utime = ti.user_time.seconds + ti.user_time.microseconds * 1e-6;
rpd->stime = ti.system_time.seconds + ti.system_time.microseconds * 1e-6;
error = task_threads(task, &thread_table, &table_size);
assert(error == KERN_SUCCESS);
thi = &thi_data;
for (i = 0; i != table_size; ++i) {
count = THREAD_BASIC_INFO_COUNT;
error = thread_info(thread_table[i], THREAD_BASIC_INFO, (thread_info_t)thi, &count);
assert(error == KERN_SUCCESS);
if ((thi->flags & TH_FLAGS_IDLE) == 0) {
rpd->utime += thi->user_time.seconds + thi->user_time.microseconds * 1e-6;
rpd->stime += thi->system_time.seconds + thi->system_time.microseconds * 1e-6;
}
if (task != mach_task_self()) {
error = mach_port_deallocate(mach_task_self(), thread_table[i]);
assert(error == KERN_SUCCESS);
}
}
error = vm_deallocate(mach_task_self(), (vm_offset_t)thread_table, table_size * sizeof(thread_array_t));
assert(error == KERN_SUCCESS);
}
mach_port_deallocate(mach_task_self(), task);
return 0;
}
#endif /* __APPLE__ */
launch your application with Instruments. put it through the paces, and evaluate the results...
Following #user172818 advice, I tried getrusage and it worked for me:
#include <sys/time.h>
#include <sys/resource.h>
long getMemoryUsage()
{
struct rusage usage;
if(0 == getrusage(RUSAGE_SELF, &usage))
return usage.ru_maxrss; // bytes
else
return 0;
}
I am using Mac OS X 10.9.4, with compiler Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn).
You can give a try to mallocDebug function : http://developer.apple.com/mac/library/DOCUMENTATION/Performance/Conceptual/ManagingMemory/Articles/FindingPatterns.html.