Linking another library from C-library in gwan/libraries results in "undefined symbol" error - g-wan

I'm trying to use a standard library libuuid inside my C-library file my_uuid.c:
gwan/libraries/my_uuid.c:
#include <uuid/uuid.h>
#pragma link "uuid"
void my_uuid_generate(uuid_t uuid)
{
uuid_generate(uuid);
}
gwan/init.c:
#include <uuid/uuid.h>
#pragma link "uuid"
#pragma link "libraries/my_uuid.c"
int main(int argc, char *argv[])
{
uuid_t uuid;
my_uuid_generate(uuid);
return 0;
}
However, G-Wan fails to start and prints such message:
Linking ./init.c: undefined symbol: uuid_generate
This mustn't be the problem of libuuid installation or non-standard path, because such servlet does work successfully:
#include <uuid/uuid.h>
#pragma link "uuid"
int main(int argc, char *argv[])
{
uuid_t uuid;
char str[256];
uuid_generate(uuid);
uuid_unparse(uuid, str);
printf("%s\n", str);
xbuf_cat(get_reply(argv), "Hello, World!");
return 200;
}
The problem might be due to that G-Wan first loads init.c and then my_uuid.c instead of libuuid, even though I have #pragma link "uuid" in init.c.
Does anybody know how to solve the problem?
Is it considered valid to link other libraries from C-file libraries in gwan/libraries?

I read GWAN's documentation. If you write your own library, you should be able to integrate well with it (treating it as a preexisting library).
myuuid.h
myuuid.c
Then generate your library, by compiling myuuid.c:
libmyuuid.a
Put the library as gwan/libraries/libuuid.a and try it as below.
#include "myuuid.h"
#pragma link "./libraries/myuuid"
int main(int argc, char *argv[])
{
my_uuid_generate();
return 0;
}
You may want to keep an eye on gwan/logs/gwan.log file to see if the link worked. You could also start GWAN server in a terminal, manually, to look at the errors.

The servlet works because you are linking your script directly to an existing library (already compiled code).
The init.c script fails to link because the "#pragma link "libraries/my_uuid.c" library that calls a compiled library does not exist yet (it's still source code).
You should rather use #include "libraries/my_uuid.c" in init.c to have this kind of constructions work.

Interestingly, G-Wan successfully started when I moved #pragma link "uuid" below the #pragma link "libraries/my_uuid.c" in init.c file:
#include <uuid/uuid.h>
#pragma link "libraries/my_uuid.c"
#pragma link "uuid"
int main(int argc, char *argv[])
{
uuid_t uuid;
my_uuid_generate(uuid);
return 0;
}
Definitely, it changed the order in which G-Wan loads libuuid and my_uuid.c. Now it first loads libuuid (with uuid_generate() symbol) and then my_uuid.c (with my_uuid_generate() symbol, which in turn calls uuid_generate()).
Gil, do I correctly understand that currently G-Wan is not designed to provide a controllable order of library loads? Can the G-Wan team consider updating the G-Wan server to load the libraries in a controllable/predicatable order, at least in some extent? I.e. load the dependencies before the dependency users.
For example we should be able to write such code as below and the G-Wan server to load first libuuid, then my_uuid.c, then init.c:
gwan/libraries/my_uuid.c:
#pragma link "uuid"
gwan/init.c:
#pragma link "libraries/my_uuid.c"
(notice no #pragma link "uuid" in init.c)

Related

SIGINT was not declared in this scope

Background
I am trying to build a sample REST api app for Rasbian running on Raspberry 3. I used cpprestsdk.
Sample contains the following header file:
#include <condition_variable>
#include <mutex>
#include <iostream>
static std::condition_variable _condition;
static std::mutex _mutex;
namespace cfx {
class InterruptHandler {
public:
static void hookSIGINT() {
signal(SIGINT, handleUserInterrupt);
}
static void handleUserInterrupt(int signal){
if (signal == SIGINT) {
std::cout << "SIGINT trapped ..." << '\n';
_condition.notify_one();
}
}
static void waitForUserInterrupt() {
std::unique_lock<std::mutex> lock { _mutex };
_condition.wait(lock);
std::cout << "user has signaled to interrup program..." << '\n';
lock.unlock();
}
};
}
Issue
When compiling on MacOS, no problem occurs.
When compiling in rasbian however, I get error: 'SIGINT' was not declared in this scope error.
It is clear that SIGINT definition - #define SIGINT 2 or similar - is not reachable when compiling on rasbian.
Question
Why I am getting this error on rasbian but not on macOS? Is it because compiler cannot locate signal.h?
I made sure that include_directories in CMakeLists.txt contains required include paths.
UPDATE
Error resolved when I manually added #include <csignal>.
You haven't included signal.h.
You're including some C++ standard library headers, and as a side effect on MacOS, these happen to include signal.h. However, that isn't specified to happen so you can't rely on it working in different implementations of those headers.
Try adding:
#include <signal.h>
at the top.
On Linux the header file to include is
#include <signal.h>
On MacOS the equivalent header file to include is
#include <csignal.h>
Depending on your OS, header files always change. They should both do the same thing though

G++ -cilkplus random behavior with std::vectors

The following (reduced) code is very badly handled by the series of GCC
#include <vector>
#include <cilk/cilk.h>
void walk(std::vector<int> v, int bnd, unsigned size) {
if (v.size() < size)
for (int i=0; i<bnd; i++) {
std::vector<int> vnew(v);
vnew.push_back(i);
cilk_spawn walk(vnew, bnd, size);
}
}
int main(int argc, char **argv) {
std::vector<int> v{};
walk(v , 5, 5);
}
Specifically:
G++ 5.3.1 crash:
red.cpp: In function ‘<built-in>’:
red.cpp:20:39: internal compiler error: in lower_stmt, at gimple-low.c:397
cilk_spawn walk(vnew, bnd, size);
G++ 6.3.1 create a code which works perfectly well if executed on one core
but segfault sometime, signal a double free some other times if using more cores. A student who
has a arch linux g++7 reported a similar result.
My question : is there something wrong with that code. Am I invoking some
undefined behavior or is it simply a bug I should report ?
Answering my own question:
According to https://gcc.gnu.org/ml/gcc-help/2017-03/msg00078.html its indeed a bug in GCC. The temporary is destroyed in the parent and not in the children in a cilk_spawn. So if the thread fork really occur, it might be destroyed too early.

How do I handle errors in Lua when executing arbitrary strings?

I'm going for absolute minimalism here. (It's been a while since I've worked with the Lua C API.)
#include <lua.hpp>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv)
{
lua_State* state = luaL_newstate();
luaL_openlibs(state);
string input;
while (getline(cin, input))
{
auto error = luaL_dostring(state, input.c_str());
if (error)
{
cerr << "Lua Error: " << lua_tostring(state, -1) << '\n';
lua_pop(state, 1);
}
}
lua_close(state);
return 0;
}
This program works fine as long as I feed it perfect Lua. However, if I enter something bad (such as asdf()), the program crashes! Why is it not handling my error gracefully?
I've tried breaking out the calls before. It crashes on the call to lua_pcall itself. I never make it past that line.
The binary download (5.2.1 I believe) has a bug that was corrected in 5.2.3. I rebuilt the library from source, and now my program works fine.

How do I use boost library with WDK environment

I wanna to compile my c plus plus project that using boost library with WDK rather than VisualStudio.
My computer's OS is Windows7-64bit, the WDK version is 7.6 and boost library version is 1.51
Once I compile my source code project, the WDK compiler will occure an error:
e:\lib\boost_1_51_0\boost\array.hpp(72) : error C2039: 'ptrdiff_t' : is not a member of 'std' .
Whole project's file contents are as follow:
File sources:
TARGETTYPE=PROGRAM
TARGETNAME=helloworld
UMENTRY=main
USE_MSVCRT=1
USE_NATIVE_EH=1
#
# use iostream package and STL
#
USE_IOSTREAM=1
USE_STL=1
STL_VER=70
#
# my boost library root directory
#
BOOST_INC_PATH=E:\lib\boost_1_51_0
INCLUDES=$(BOOST_INC_PATH)
TARGETLIBS=$(SDK_LIB_PATH)\user32.lib
SOURCES=HelloWorld.cpp
UMTYPE=console
UMBASE=0x4000000
File HelloWorld.cpp:
#include <iostream>
#include <vector>
#include <string>
#include <boost/array.hpp>
void InvokeVector()
{
//invoke STL's vector
std::vector<std::string> vec;
vec.push_back("Entry ");
vec.push_back("of ");
vec.push_back("Vector");
vec.push_back("……\n");
//print vec
for (int i=0; i<vec.size(); i++) {
std::cout<<vec.at(i);
}
}
void InvokeBoost()
{
//invoke Boost's array<T, N>
boost::array<int, 3> arr = {1, 2, 3};
for (int i=0; i<arr.size(); i++) {
std::cout<<"arr["<<i<<"]"<<"is" <<arr[i]<<std::endl;
}
}
int main()
{
// InvokeVector(); //run normally
InvokeBoost(); //it will occure an error
return 0;
}
Could you please teach me how to solve this problem? Any help will be greatly appreciated!
Short answer: No.
But you can port some.
It's well explained here : The NT Insider:Guest Article: C++ in an NT Driver
One of the main problems with C++ in the
kernel is that most of the "nice" features of the language are not
directly available in that mode. Some are easy to recreate and we will
see how to do that. However, some features should be forgotten such as
C++ exceptions, which are not the same as kernel exceptions.
Such features have to be forgotten simply because there is no support
for them in kernel mode. Translation: does not compile. If you have
the time and energy you may attempt to port them to kernel mode, but
frankly, exceptions are too slow for kernel mode. This will have an
impact on your C++ coding style, which is something you should keep in
mind.
longer answer - yes
just add
typedef int ptrdiff_t;
before pulling in boost headers and all will be well for basic boostness

Can't Build a simple Cuda Program using Xcode !

I'm using Xcode 3.2 on Mac OS 10.6 to build a very simple HelloWorld program for CUDA
but it fails to build .. any ideas !!!
this is the code :
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <CUDA/CUDA.h>
__device__ char napis_device[14];
__global__ void helloWorldOnDevice(void){
napis_device[0]='H';
napis_device[1]='e';
napis_device[2]='l';
napis_device[3]='l';
napis_device[4]='o';
napis_device[5]=' ';
napis_device[6]='W';
napis_device[7]='o';
napis_device[8]='r';
napis_device[9]='l';
napis_device[10]='d';
napis_device[11]='\n';
}
int main (int argc, char * const argv[]) {
helloWorldOnDevice<<<1,1>>> ();
cudaThreadSynchronize();
char napis_host[14];
const char *symbol="napis device";
cudaMemcpyFromSymbol (napis_host, symbol, sizeof(char)*13, 0, cudaMemcpyDeviceToHost);
return 0;
}
The error appears at this line
helloWorldOnDevice<<<1,1>>> ();
Expected primary-expression before '<' token !!!!!!
You're compiling your program with gcc coming with Xcode. Should use nvcc compiler instead to compile CUDA code. Normally I would use a Makefile to tell that *.cu to be compiled by nvcc and *.cpp by gcc, then link produced objects to an executable.

Resources