dlmopen causes zmq error "Interrupted system call" - zeromq

I'm trying to use dlmopen() in order to launch the same .so file with few instances.
Because I the shared object includes few static methods, I have to use dlmopen() in order to create due instances of it.
For each instance (all in the same thread,if it matters), in the constructor I use:
handle_ = dlmopen(LM_ID_NEWLM, "path_to_so", RTLD_LAZY | RTLD_DEEPBIND);
and I get no errors, I'm even able to use dlsym() to invoke functions from the so file:
int (*function_name)(int, const char *);
function_name = (int (*)(int, const char *))(unsigned long)dlsym(handle_, "function_name");
The thing that happens is when I try to use any kind of "zmq send" method (the receive works well) I get:
terminate called after throwing an instance of 'zmq::error_t'
what(): Interrupted system call
even after I terminate the object of the dlmopen() and the object that created them.
Has anyone encountered this kind of problem? I tried to change the flags of the dlmopen() with no luck.
This is the code for zmq_send():
inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
{
int nbytes = zmq_send (ptr, buf_, len_, flags_);
if (nbytes >= 0)
return (size_t) nbytes;
if (zmq_errno () == EAGAIN)
return 0;
throw error_t ();
}

Related

compiler segfault when printf is added (gcc 10.2 aarch64_none-elf- from arm)

I know this is not adequate for stack overflow question, but ..
This is a function in scripts/dtc/libfdt/fdt_ro.c of u-boot v2021.10.
const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
const char *name, int namelen, int *lenp)
{
int poffset;
const struct fdt_property *prop;
printf("uuu0 nodeoffset = 0x%x, name = %s, namelen = %d\n", nodeoffset, name, namelen);
prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp,
&poffset);
//printf("uuu1 prop = 0x%lx, *lenp = 0x%x, poffset = 0x%x\n", prop, *lenp, poffset);
if (!prop)
return NULL;
/* Handle realignment */
if (fdt_chk_version() && fdt_version(fdt) < 0x10 &&
(poffset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8)
return prop->data + 4;
return prop->data;
}
When I build the program, if I uncomment the second printf, the compiler seg-faults.
I have no idea. Is it purely compiler problem(I think so it should never die at least)? or can it be linked to my fault somewhere in another code? Is there any method to know the cause of the segfault? (probably not.).
If you're getting a segmentation fault when running the compiler itself, the compiler has a bug. There are some errors in your code, but those should result in compile-time diagnostics (warnings or error messages), never a compile-time crash.
The code in your question is incomplete (missing declarations for fdt_get_property_namelen_, printf, NULL, etc.). Reproduce the problem with a complete self-contained source file and submit a bug report: https://gcc.gnu.org/bugzilla/
printf("uuu1 prop = 0x%lx, *lenp = 0x%x, poffset = 0x%x\n", prop, *lenp, poffset);
prop is a pointer, so I'd use %p instead of %lx
lenp is a pointer, so I'd make sure that it points to valid memory

Why _makepath_s does not return on error?

According to https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/makepath-s-wmakepath-s?view=vs-2019#generic-text-routine-mappings _makepath_s should return an error code on failure.
On my system this is not true, it gives an assert (Expression: (L"Buffer is too small" && 0)) and then terminates the program. In release it simply terminates the program.
The only way I found to keep my program running is to set an empty invalid parameter handler:
void myInvalidParameterHandler(const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
}
_set_invalid_parameter_handler(myInvalidParameterHandler);
But this is not recommended. The docs say that this handler should abort the program.
And I also think that this modifies all secure function which is not what exactly what I want.
So is there a better way to get _makepath_s behave like the docs say?
TIA Michael
VS2017, MFC
Edit
A small sample:
char Path[_MAX_PATH];
char drive[_MAX_DRIVE] = "C:";
char dir[_MAX_DIR] = "Thisisaverylongdirname01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
char fname[_MAX_FNAME] = "Thisisaverylongfilename012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
char ext[_MAX_EXT] = "txt";
_makepath(Path, drive, dir, fname, ext);

running boost: lock free queues globally across multiple files

I would like to run a variant of example 46.3 from this website
http://theboostcpplibraries.com/boost.lockfree. I am on a linux system.
I would like to have the queue q be defined in a header file. I would like to have the produce and consume functions be in different files. So I would like to have global.h contain
static boost::lockfree::queue<int> q{100};
static std::atomic<int> sum{0};
void *produce (void*);
void *consume (void*);
I would then like to have a produce.cpp contain:
void *produce( void*)
{
for (int i = 1; i <= 10000; ++i)
q.push(i);
}
and I would like to have a consume.cpp contain
void *consume (void*)
{
int i;
while (q.pop(i))
sum += i;
}
I would then like to have my main.cpp contain
#include iosteam
#include iomanip
#include global
#include pthread
int main ()
{pthread_t t1;
pthread_t t2;
pthread_t t3;
int t1_iret;
t1_iret = pthread_create( &t1, NULL, produce, NULL);
if(t1_iret)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",t1_iret);
exit(EXIT_FAILURE);
}
int t2_iret;
t2_iret = pthread_create( &t2, NULL, consume, NULL);
if(t2_iret)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",t2_iret);
exit(EXIT_FAILURE);
}
int t3_iret;
t3_iret = pthread_create( &t3, NULL, consume, NULL);
if(t3_iret)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",t3_iret);
exit(EXIT_FAILURE);
}
pthread_join( t1, NULL);
pthread_join( t2, NULL);
pthread_join( t3, NULL);
return 0; }
Additionally, I was wondering if it would be possible to do what I have described with strings rather then integers.
edit1: when I try and make the queue be queue of strings I get::
/usr/local/include/boost/lockfree/queue.hpp: In instantiation of ‘class boost::l ockfree::queue >’:
/home/ubuntu/Project/src/main.cpp:15:37: required from here
/usr/local/include/boost/lockfree/queue.hpp:87:5: error: static assertion failed : (boost::has_trivial_destructor::value)
BOOST_STATIC_ASSERT((boost::has_trivial_destructor::value));
^
/usr/local/include/boost/lockfree/queue.hpp:91:5: error: static assertion failed : (boost::has_trivial_assign::value)
BOOST_STATIC_ASSERT((boost::has_trivial_assign::value));
^
In file included from /usr/local/include/boost/lockfree/queue.hpp:21:0,
from /home/ubuntu/Project/src/main.cpp:5:
/usr/local/include/boost/lockfree/detail/copy_payload.hpp: In instantiation of ‘ static void boost::lockfree::detail::copy_constructible_and_copyable::copy(T&, U &) [with T = std::basic_string; U = int]’:
/usr/local/include/boost/lockfree/detail/copy_payload.hpp:49:25: required from ‘void boost::lockfree::detail::copy_payload(T&, U&) [with T = std::basic_string ; U = int]’
/usr/local/include/boost/lockfree/queue.hpp:402:61: required from ‘bool boost: :lockfree::queue::pop(U&) [with U = int; T = std::basic_string; A0 = boost::parameter::void_; A1 = boost::parameter::void_; A2 = boost::par ameter::void_]’
/home/ubuntu/Project/src/main.cpp:21:24: required from here
/usr/local/include/boost/lockfree/detail/copy_payload.hpp:38:11: error: invalid cast from type ‘std::basic_string’ to type ‘int’
u = U(t);
You need to declare, but not define, your variables in global.h:
extern boost::lockfree::queue<int> q;
extern std::atomic<int> sum;
Then you need to define them in a separate file, global.cpp:
boost::lockfree::queue<int> q{100};
std::atomic<int> sum{0};
I think this should fix your issue. For details, see How do I use extern to share variables between source files?
As for the second part, asking why you can't make a lock-free queue of strings, well, that is answered by the error message: has_trivial_destructor is false for std::string, because it's a dynamically-sized string which allocates memory. You won't be able to use it in this sort of lock-free queue. You can try using a fixed-size string class instead, or std::array<char, N>.

using system call in Linux kernel file

I am implementing a custom process scheduler in Linux. And I want to use a system call to record my program so that I can debug easily.
The file I write is
source code : linux-x.x.x/kernel/sched_new_scheduler.c
In sched_new_scheduler.c could I use syscall(the id of the system call, parameter); directly? It seems syscall(); is used with #include<sys/syscalls.h> in C program, but the ".h" can not be found in the kernel/.
I just want to know how my program executes by recording something, so could I directly write printk("something"); in sched_new_scheduler.c ? Or try a correct way to use system call?
System call look like wrapper around other kernel function one of ways how to use syscall inside kernel is find sub function for exact system call. For example:
int open(const char *pathname, int flags, mode_t mode); -> filp_open
////////////////////////////////////////////////////////////////////////////////////////////////
struct file* file_open(const char* path, int flags, int rights)
{
struct file* filp = NULL;
mm_segment_t oldfs;
int err = 0;
oldfs = get_fs();
set_fs(get_ds());
filp = filp_open(path, flags, rights);
set_fs(oldfs);
if(IS_ERR(filp)) {
err = PTR_ERR(filp);
return NULL;
}
return filp;
}
ssize_t write(int fd, const void *buf, size_t count); -> vfs_write
////////////////////////////////////////////////////////////////////////////////////////////////
int file_write(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
{
mm_segment_t oldfs;
int ret;
oldfs = get_fs();
set_fs(get_ds());
ret = vfs_write(file, data, size, &offset);
set_fs(oldfs);
return ret;
}
A system call is supposed to be used by an application program to avail a service from kernel. You can implement a system call in your kernel module, but that should be called from an application program. If you just want to expose the statistics of your new scheduler to the userspace for debugging, you can use interfaces like proc, sys, debugfs etc. And that would be much more easier than implementing a system call and writing a userspace application to use it.

CUDA constant memory issue: invalid device symbol with cudaGetSymbolAddress

I am trying to set constant values on my GPU's constant memory before launching a kernel which needs these values.
My code (simplified):
__constant__ size_t con_N;
int main()
{
size_t N;
size_t* dev_N = NULL;
cudaError_t cudaStatus;
//[...]
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, &con_N);
if (cudaStatus != cudaSuccess) {
cout<<"cudaGetSymbolAddress (dev_N) failed: "<<cudaGetErrorString(cudaStatus)<<endl;
}
I planned to cudaMemcpy my N to dev_N afterwards.
However, all I get at this point in the code is:
cudaGetSymbolAddress (dev_N) failed: invalid device symbol
I'm working with CUDA 6.5 so it's not a quoted symbol issue, as it is in most of the Q&A I've been checking so far.
I tried to replace con_N with con_N[1] (and remove the & before con_N in cudaGetSymbolAddress parameters): same result.
As the prototype of this function is cudaGetSymbolAddress(void **devPtr , const void* symbol ), I guessed it wanted to be given my symbol's address. However, I tried with cudaStatus = cudaGetSymbolAddress((void **)&dev_N, (const void*) con_N); and I got the same message.
I'm also getting the very same error message when I remove cudaGetSymbolAddress((void **)&dev_N, &con_N) and go directly with cudaMemcpyToSymbol(&con_N, &N, sizeof(size_t)) instead.
I'm afraid I missed something essential. Any help will be greatly appreciated.
The correct usage of cudaGetSymbolAddress is
cudaGetSymbolAddress((void **)&dev_N, con_N)
I'm showing this with the simple example below.
As the documentation explains, the symbol should physically reside on the device. Accordingly, using &con_N in the API call appears to be meaningless, since, being cudaGetSymbolAddress a host API, accessing the address of something residing on the device directly from host should not be possible. I'm not sure if the prototype appearing in the CUDA Runtime API document should better read as `
template<class T>
cudaError_t cudaGetSymbolAddress (void **devPtr, const T symbol)
with device symbol reference instead of device symbol address.
#include <stdio.h>
__constant__ int const_symbol;
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
/***************/
/* TEST KERNEL */
/***************/
__global__ void kernel() {
printf("Address of symbol from device = %p\n", &const_symbol);
}
/********/
/* MAIN */
/********/
int main()
{
const int N = 16;
int *pointer = NULL;
gpuErrchk(cudaGetSymbolAddress((void**)&pointer, const_symbol));
kernel<<<1,1>>>();
printf("Address of symbol from host = %p\n", pointer);
return 0;
}
In my opinion, A line of your code should be fixed like below.
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, con_N);
Hope this helps you.

Resources