When I run a GTK with Glade I get the following warning - Could not find signal handler 'on_window_main_destory'. Did you compile with -rdnamic? - gtk

#include <gtk/gtk.h>
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
void pop_class()
{
CURL *curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "http://api.openweathermap.org/data/2.5/forecast id=2158867&appid=a4f247bfd153738d2cd1757224361972");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
}
int main(int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *window;
gtk_init(&argc, &argv);
builder = gtk_builder_new_from_file("glade/window_main.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
gtk_builder_connect_signals(builder, NULL);
g_object_unref(builder);
gtk_widget_show(window);
gtk_main();
pop_class();
return 0;
}
// called when window is closed
void on_window_main_destroy()
{
gtk_main_quit();
}
this compiles correctly with
g++ -c -g -O0 -Wall -pthread -pipe src/main.cpp -lcurl `pkg-config --cflags --libs gtk+-3.0` -o main.o
and then this
g++ -o temp_app main.o -pthread `pkg-config --cflags --libs gtk+-3.0`
-export-dynamic
and on running I get the following warning -
Could not find signal handler 'on_window_main_destory'. Did you compile with -rdnamic?

GTK Builder wasn't really designed to interface with signal callbacks in C++ or other languages; C++ functions are so-called name mangled, which means that the real name of a particular function is likely quite different from the name the function is given in the source code. Your on_window_main_destroy function may well actually have a name like: _Zxl65Abvon_window_main_destroyxxj, depending on the compiler in use. This mangling is done to encode the function's namespace, parameter types, and return values among other things, so that overloading can work -- i.e., so that you can have two or more different functions with what looks like the same name, but which accept or return different parameters.
As such I'd really suggest using the g_signal_connect function on window, like this:
g_signal_connect (window, "destroy", G_CALLBACK (on_window_main_destroy), NULL);
However, if you must reference the callback from a Builder file, then surround the callback function with an extern "C" { } block, as such:
extern "C"
{
void on_window_main_destroy()
{
gtk_main_quit();
}
}
...or to simplify things a little:
extern "C" void on_window_main_destroy()
{
gtk_main_quit();
}
You may also be able to take a shortcut here by simply setting the callback in your Builder file to gtk_main_quit. By doing such, you can avoid creating a function of your own altogether.

Related

why setuid fails after capset is used?

trying to figure out the linux capabilities interface, i came across with an unexpected issue (for me at least). When seting the capabilities of a process with the capset syscall the kernel rejects a change of userid with the setuid syscall. Does anybody know why setuid fails?
This is code i wrote to test this behavior:
#undef _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/capability.h>
#include <sys/capability.h>
#include <string.h>
int main(int argc, char** argv){
struct __user_cap_header_struct cap_header;
struct __user_cap_data_struct cap_data;
int cap_res;
FILE *file;
int sockfd;
cap_header.pid = getpid();
cap_header.version = _LINUX_CAPABILITY_VERSION_1;
__u32 cap_mask = 0;
cap_mask |= (1 << CAP_DAC_OVERRIDE);
cap_mask |= (1 << CAP_SETUID);
printf("You selected mask: %x\n", cap_mask);
cap_data.effective = cap_mask;
cap_data.permitted = cap_mask;
cap_data.inheritable = cap_mask;
cap_res = capset(&cap_header, &cap_data);
if(cap_res < 0){
printf("Trying to apply mask: FAIL\n", cap_mask);
} else {
printf("Capability set correctly\n");
}
int uid = atol(argv[1]);
int setuid_res = setuid(uid);
if (setuid_res == -1){
printf("7w7\n");
} else {
printf("UID set correctly\n");
}
}
compiled with:
$ gcc -g test1.c -o test1
Output is (for user id: 1000)
$ # ./test1 1000
You selected mask: 2
Capability set correctly
7w7
I think you might be missing a couple of steps in your question:
How do you give the binary some privilege?
It looks like you are trying to use cap_dac_override to achieve what cap_setuid is intended for.
Rewriting the program as follows:
#undef _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/capability.h>
#include <sys/capability.h>
#include <string.h>
int main(int argc, char** argv){
struct __user_cap_header_struct cap_header;
struct __user_cap_data_struct cap_data;
int cap_res;
// need to start from known data. C does not guarantee these are
// zero filled by default. You could declare them static to get
// that.
memset(&cap_header, 0, sizeof(cap_header));
memset(&cap_data, 0, sizeof(cap_data));
cap_header.pid = getpid();
cap_header.version = _LINUX_CAPABILITY_VERSION_1;
__u32 cap_mask = 0;
cap_mask |= (1 << CAP_SETUID);
printf("You selected mask: %x\n", cap_mask);
cap_data.effective = cap_mask;
cap_data.permitted = cap_mask;
// not needed: cap_data.inheritable = cap_mask;
cap_res = capset(&cap_header, &cap_data);
if(cap_res < 0){
printf("Trying to apply mask: FAIL\n", cap_mask);
exit(1);
} else {
printf("Capability set correctly\n");
}
if (argc != 2) {
printf("usage: %s <uid>\n", argv[0]);
exit(1);
}
int uid = atol(argv[1]);
int setuid_res = setuid(uid);
if (setuid_res == -1){
printf("7w7\n");
} else {
printf("UID set correctly to %d\n", uid);
}
}
You can run the program like this:
$ sudo ./test1 1000
You selected mask: 80
Capability set correctly
UID set correctly to 1000
Or, using a file capability:
$ sudo setcap cap_setuid=p ./test1
$ ./test1 1000
You selected mask: 80
Capability set correctly
UID set correctly to 1000
This will work if you want to use the first 32 capabilities. However, there are ~40 of them under Linux at present, so I'd suggest you look into using the libcap API instead which figures out all of the kernel ABI details for you.

Cuda warp illegal address

I'm having some trouble with CUDA and passing classes to a kernel. I've some functions which allocate memory for the class on the GPU, pass it, and work fine. There is another one, though, that just won't work. I noticed that it happens only when I'm working with arrays. Here is an example.
File1.hh
#ifndef PROVA1_HH
#define PROVA1_HH
#include <cstdio>
class cls {
public:
int *x, y;
cls();
void kernel();
};
#endif
File1.cu
#include "Prova1.hh"
__global__ void kernel1(cls* c){
printf("%d\n", c->y);
c->y=2;
printf("%d\n", c->y);
c->x[0]=0; c->x[1]=1;
printf("%d %d\n", c->x[0], c->x[1]);
}
void cls::kernel(){
cls* dev_c; cudaMalloc(&dev_c, sizeof(cls));
cudaMemcpy(dev_c, this, sizeof(cls), cudaMemcpyHostToDevice);
printf("(%d, %d)\n", x[0], x[1]);
kernel1<<<1, 1>>> (dev_c);
cudaDeviceSynchronize();
cudaMemcpy(this, dev_c, sizeof(cls), cudaMemcpyDeviceToHost);
printf("(%d, %d)\n", x[0], x[1]);
}
cls::cls(){
y=3;
x=(int*) malloc(sizeof(int)*2);
x[0]=1; x[1]=2;
}
File.cu
#include<cstdio>
#include "Prova1.hh"
int main(){
cls c=cls();
c.kernel();
return 0;
}
I'm compiling with:
nvcc -std=c++11 -arch=sm_35 -rdc=true -c -o File1.o File1.cu
nvcc -std=c++11 -arch=sm_35 -rdc=true -g -G -o File.out File1.o File.cu
When I simpy run it, the output would be:
(1, 2)
3
2
(1, 2)
When I debug it, I get:
Starting program:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fb10eb1e0 (LWP 806)]
(1, 2)
CUDA Exception: Warp Illegal Address
The exception was triggered at PC 0x84fa10
Thread 1 "File.out" received signal CUDA_EXCEPTION_14, Warp Illegal Address.
[Switching focus to CUDA kernel 0, grid 1, block (0,0,0), thread (0,0,0), device 0, sm 0, warp 0, lane 0]
0x000000000084fad0 in kernel1(ciao*)<<<(1,1,1),(1,1,1)>>> ()
Do any of you guys know were I'm making mistakes?
There is a lot broken in that code you posted, but the core source of the error is that you are attempting to access a host pointer inside the kernel (no memory is ever allocated to x on the device and the values are not copied either). Unless you use managed memory, that is obviously never going to work.
You could rework your example into something like this:
#include <cstdio>
class cls {
public:
int *x, y;
__host__ __device__
cls(int *x_, int y_) : x(x_), y(y_) {};
void kernel();
};
__global__ void kernel1(cls* c){
printf("%d\n", c->y);
c->y=2;
printf("%d\n", c->y);
c->x[0]=0; c->x[1]=1;
printf("%d %d\n", c->x[0], c->x[1]);
}
void cls::kernel(){
int* dev_x; cudaMalloc(&dev_x, sizeof(int)*2);
cudaMemcpy(dev_x, x, sizeof(int)*2, cudaMemcpyHostToDevice);
cls h_dev_c(dev_x, y);
cls* dev_c; cudaMalloc(&dev_c, sizeof(cls));
cudaMemcpy(dev_c, &h_dev_c, sizeof(cls), cudaMemcpyHostToDevice);
printf("(%d)\n", y);
printf("(%d, %d)\n", x[0], x[1]);
kernel1<<<1, 1>>> (dev_c);
cudaDeviceSynchronize();
cudaMemcpy(&y, &(dev_c->y), sizeof(int), cudaMemcpyDeviceToHost);
cudaMemcpy(x, dev_x, sizeof(int)*2, cudaMemcpyDeviceToHost);
printf("(%d)\n", y);
printf("(%d, %d)\n", x[0], x[1]);
}
int main(){
int y=3;
int* x=(int*) malloc(sizeof(int)*2);
x[0]=1; x[1]=2;
cls c(x,y);
c.kernel();
return 0;
}
Note that you have to basically build a device copy of the class in host memory and then copy that to the device to make this work correctly (this is a very common design pattern for arrays of pointers or structures and classes containing pointers, although it is almost never recommended for complexity and performance reasons).

international chars in tcl/tk can't be handle

I use tcl shellicon command to extract icons, as it mentioned on wiki page below, there are some international character problems in it, then I write some code to test but it doesn't work, could anyone to help me correct it.
/*
* testdll.c
* gcc compile: gcc testdll.c -ltclstub86 -ltkstub86 -IC:\Users\L\tcc\include -IC:\Users\L\tcl\include -LC:\Users\L\tcl\lib -LC:\Users\L\tcc\lib -DUSE_TCL_STUBS -DUSE_TK_STUBS -shared -o testdll.dll
*/
#include <windows.h>
#include <tcl.h>
#include <stdlib.h>
int TestdllCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) {
char * path;
Tcl_DString ds;
if (objc > 2) {
Tcl_SetResult(interp, "Usage: testdll ?path?",NULL);
return TCL_ERROR;
}
if (objc == 2) {
path = Tcl_GetString(objv[objc-1]);
path = Tcl_TranslateFileName(interp, path, &ds);
if (path != TCL_OK) {
return TCL_ERROR;
}
}
Tcl_AppendResult(interp, ds, NULL);
return TCL_OK;
}
int DLLEXPORT Testdll_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "testdll", TestdllCmd, NULL, NULL);
Tcl_PkgProvide(interp, "testdll", "1.0");
return TCL_OK;
}
I compile it with:
gcc compile: gcc testdll.c -ltclstub86 -ltkstub86 -IC:\Users\USERNAME\tcc\include -IC:\Users\USERNAME\tcl\include -LC:\Users\USERNAME\tcl\lib -LC:\Users\USERNAME\tcc\lib -DUSE_TCL_STUBS -DUSE_TK_STUBS -shared -o testdll.dll
windows cmd shell run: tclsh testdll.tcl
load testdll
puts [testdll C:/Users/L/桌面]
the output is:
// This line isn't in the output, just to show the first line of output is a *EMPTY LINE*
while executing
"testdll 'C:/Users/L/桌面'"
invoked from within
"puts [testdll 'C:/Users/L/桌面']"
(file "testdll.tcl" line 2)
In fact, I want to print a line, whose content is "C:/Users/L/桌面"
I write this dll to debug how to replace Tcl_GetString,Tcl_TranslateFileName with Tcl_FSGetNormalizedPath, Tcl_FSGetNativePath, I wonder if it's clear?
Thank you!
Remove this:
if (path != TCL_OK) {
return TCL_ERROR;
}
You are comparing a char * to an int.
The manual page for Tcl_TranslateFileName says:
However, with the advent of the newer Tcl_FSGetNormalizedPath
and Tcl_FSGetNativePath, there is no longer any need to use this
procedure.
You should probably switch to more modern API call.

perl match function for C program

Trying to use perl API functions in C program. Couldn't find the function to do regular expression match. Wish there is a function like regexmatch in the following program.
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include <sys/time.h>
typedef unsigned long ulong;
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
int main(int argc, char **argv, char **env) {
int numOfArgs = 0;
PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
SV* str = newSVpv(argv[1], strlen(argv[1]));
if (regexmatch(str, "/hi (\S+)/")) {
printf("found a match\n");
}
return 0;
}
I know it's possible to use pcre library, just wonder if it's possible to get it from perl library here (libperl.so.5.14.2 on ubuntu 12.04)
Thanks!
UPDATE 1:
Did some google search and got the following simple program compiling. But when I ran the program as ./a.out ping pin, it gave "Segmentation fault" in the "pregcomp" function. Not sure why.
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include <sys/time.h>
#include <embed.h>
typedef unsigned long ulong;
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
struct REGEXP * const engine;
int main(int argc, char **argv, char **env) {
int numOfArgs = 0;
PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
SV* reStr = newSVpv(argv[2], strlen(argv[2]));
printf("compiling regexp\n");
REGEXP * const compiled_regex = pregcomp(reStr, 0);
printf("execing regexp\n");
int len = strlen(argv[1]);
pregexec(compiled_regex, argv[1], argv[1] + len, argv[1], 5, NULL, 0);
return 0;
}
Don't mess with Perl's private internals. Call a Perl sub that uses the match operator.
Say you previously compiled the following in your interpreter (using eval_pv),
sub regex_match { $_[0] =~ $_[1] }
Then you can call
static bool regex_match_sv(SV* str, SV* re) {
dSP;
bool matched;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(str);
XPUSHs(re);
PUTBACK;
call_pv("regex_match", G_SCALAR);
SPAGAIN;
matched = SvTRUE(POPs);
PUTBACK;
FREETMPS;
LEAVE;
return matched;
}

Creating Threaded callbacks in XS

EDIT: I have created a ticket for this which has data on an alternative to this way of doing things.
I have updated the code in an attempt to use MY_CXT's callback as gcxt was not storing across threads. However this segfaults at ENTER.
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifndef aTHX_
#define aTHX_
#endif
#ifdef USE_THREADS
#define HAVE_TLS_CONTEXT
#endif
/* For windows */
#ifndef SDL_PERL_DEFINES_H
#define SDL_PERL_DEFINES_H
#ifdef HAVE_TLS_CONTEXT
PerlInterpreter *parent_perl = NULL;
extern PerlInterpreter *parent_perl;
#define GET_TLS_CONTEXT parent_perl = PERL_GET_CONTEXT;
#define ENTER_TLS_CONTEXT \
PerlInterpreter *current_perl = PERL_GET_CONTEXT; \
PERL_SET_CONTEXT(parent_perl); { \
PerlInterpreter *my_perl = parent_perl;
#define LEAVE_TLS_CONTEXT \
} PERL_SET_CONTEXT(current_perl);
#else
#define GET_TLS_CONTEXT /* TLS context not enabled */
#define ENTER_TLS_CONTEXT /* TLS context not enabled */
#define LEAVE_TLS_CONTEXT /* TLS context not enabled */
#endif
#endif
#include <SDL.h>
#define MY_CXT_KEY "SDL::Time::_guts" XS_VERSION
typedef struct {
void* data;
SV* callback;
Uint32 retval;
} my_cxt_t;
static my_cxt_t gcxt;
START_MY_CXT
static Uint32 add_timer_cb ( Uint32 interval, void* param )
{
ENTER_TLS_CONTEXT
dMY_CXT;
dSP;
int back;
ENTER; //SEGFAULTS RIGHT HERE!
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(interval)));
PUTBACK;
if (0 != (back = call_sv(MY_CXT.callback,G_SCALAR))) {
SPAGAIN;
if (back != 1 ) Perl_croak (aTHX_ "Timer Callback failed!");
MY_CXT.retval = POPi;
} else {
Perl_croak(aTHX_ "Timer Callback failed!");
}
FREETMPS;
LEAVE;
LEAVE_TLS_CONTEXT
dMY_CXT;
return MY_CXT.retval;
}
MODULE = SDL::Time PACKAGE = SDL::Time PREFIX = time_
BOOT:
{
MY_CXT_INIT;
}
SDL_TimerID
time_add_timer ( interval, cmd )
Uint32 interval
void *cmd
PREINIT:
dMY_CXT;
CODE:
MY_CXT.callback=cmd;
gcxt = MY_CXT;
RETVAL = SDL_AddTimer(interval,add_timer_cb,(void *)cmd);
OUTPUT:
RETVAL
void
CLONE(...)
CODE:
MY_CXT_CLONE;
This segfaults as soon as I go into ENTER for the callback.
use SDL;
use SDL::Time;
SDL::init(SDL_INIT_TIMER);
my $time = 0;
SDL::Timer::add_timer(100, sub { $time++; return $_[0]} );
sleep(10);
print "Never Prints";
Output is
$
it should be
$ Never Prints
Quick comments:
Do not use Perl structs (SV, AV, HV, ...) outside of the context of a Perl interpreter object. I.e. do not use it as C-level static data. It will blow up in a threading context. Trust me, I've been there.
Check out the "Safely Storing Static Data in XS" section in the perlxs manpage.
Some of that stuff you're doing looks rather non-public from the point of view of the perlapi. I'm not quite certain, though.
$time needs to be a shared variable - otherwise perl works with separate copies of the variable.
My preferred way of handling this is storing the data in the PL_modglobal hash. It's automatically tied to the current interpreter.
We have found a solution to this using Perl interpreter threads and threads::shared. Please see these
Time.xs
Also here is an example of a script using this code.
TestTimer.pl