How to implement IDkmCustomVisualizer for managed target - visual-studio-debugging

So far I was able to run and this sample that implement this interface and using it for debug C++ apps.
I try to implement IDkmCustomVisualizer in C#, aiming use it to debug CLR apps. Is this possible ?
I retrofitted Hello Wrold sample, where added class that implement IDkmCustomVisualizer and changed HelloWorld.vsdconfigxml. But nothing works, debugger in experimental instance do not use this implementation. Tried with VS 2017 and 2019 Community.
my IDkmCustomVisualizer implementation:
public class CSF : IDkmCustomVisualizer
{
void crf()
{
System.IO.File.Delete("c:/uuu.txt");
System.IO.File.WriteAllText("c:/uuu.txt", "ooo");
}
void IDkmCustomVisualizer.EvaluateVisualizedExpression(DkmVisualizedExpression visualizedExpression, out DkmEvaluationResult resultObject)
{
crf();
visualizedExpression.EvaluateVisualizedExpression(out resultObject);
}
void IDkmCustomVisualizer.UseDefaultEvaluationBehavior(DkmVisualizedExpression visualizedExpression, out bool useDefaultEvaluationBehavior, out DkmEvaluationResult defaultEvaluationResult)
{
crf();
visualizedExpression.UseDefaultEvaluationBehavior(out useDefaultEvaluationBehavior, out defaultEvaluationResult);
}
void IDkmCustomVisualizer.GetChildren(DkmVisualizedExpression visualizedExpression, int initialRequestSize, DkmInspectionContext inspectionContext, out DkmChildVisualizedExpression[] initialChildren, out DkmEvaluationResultEnumContext enumContext)
{
crf();
visualizedExpression.GetChildren(initialRequestSize, inspectionContext, out initialChildren, out enumContext);
}
void IDkmCustomVisualizer.GetItems(DkmVisualizedExpression visualizedExpression, DkmEvaluationResultEnumContext enumContext, int startIndex, int count, out DkmChildVisualizedExpression[] items)
{
crf();
visualizedExpression.GetItems(enumContext, startIndex, count, out items);
}
void IDkmCustomVisualizer.SetValueAsString(DkmVisualizedExpression visualizedExpression, string value, int timeout, out string errorText)
{
crf();
visualizedExpression.SetValueAsString(value, timeout, out errorText);
}
string IDkmCustomVisualizer.GetUnderlyingString(DkmVisualizedExpression visualizedExpression)
{
crf();
var ret = visualizedExpression.GetUnderlyingString();
return ret;
}
}
and HelloWorld.vsdconfigxml
<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="http://schemas.microsoft.com/vstudio/vsdconfig/2008">
<ManagedComponent
ComponentId="C4256689-AC45-4B10-BFD3-4036CEE1863A"
ComponentLevel="9992000"
AssemblyName="HelloWorld">
<Class Name="HelloWorld.CSF" >
<Implements>
<InterfaceGroup>
<NoFilter></NoFilter>
<Interface Name="IDkmCustomVisualizer"/>
</InterfaceGroup>
</Implements>
</Class>
</ManagedComponent>
</Configuration>
Thanks in advance

Pierson's advice for analyze logs was helpful, and finally I was able to run IDkmCustomVisualizer implemented in C# but only for debugging C++ apps. For managed apps it is not called.
Found good alternative IDkmLanguageExpressionEvaluator that implemented in C# is called by both managed and unmagaged (C++) apps.

Related

Define a C API with callbacks

I'm a Java/C++ programmer trying to write a portable C API. It's a big state-machine with lots of states, and I need a way for the user to provide functionality for each individual state.
In Java or C++, I would define an Interface or Pure Virtual class with all the parse functionality, like so:
class StateHandler {
public:
virtual void handleState1(const StateData &data) = 0;
virtual void handleState2(const StateData &data) = 0;
// ...
}
class StateMachine {
public:
StateMachine(StateHandler &handler) : _handler(handler) {}
void transition(const StateInput &input);
private:
StateHandler &_handler;
}
StateMachine::transition(const StateInput &input) {
StateData state_data;
// ... stuff ...
_handler.handleState1(state_data);
}
I'm wondering what's the best way to do this in C? Two ideas come to mind... the first is essentially a copy of the "class" approach above, but using structs and function pointers:
struct state_handler_t {
void (*handleState1)(void *user_data, state_data_t *state_data);
void (*handleState2)(void *user_data, state_data_t *state_data);
// ...
};
struct state_machine_t {
// opaque details of state machine
// ...
// pointer to user-provided data
void* user_data;
};
state_machine_t *new_state_machine(void* user_data) {
// ...
}
transition(state_machine_t *state_machine, state_handler_t *callback) {
state_data_t state_data;
// ... stuff ...
callback->handleState1(state_machine->user_data, &state_data);
}
This feels like I'm trying to program in the languages I know (using OOP) rather than embracing the language I'm using.
The other alternative I considered is to forward declare all the handler functions, and let the caller link in their implementations:
void handleState1(void *user_data, state_data_t *state_data);
void handleState2(void *user_data, state_data_t *state_data);
// ...
// state_machine_t same as above
transition(state_machine_t *state_machine) {
state_data_t state_data;
// ... stuff ...
handleState1(state_machine->user_data, &state_data);
}
The issue I have with this one is that I'm preventing users from defining more than one handler implementation.
Any pointers (pardon the pun) or words of wisdom from you C gurus?
Thanks!

SGX Enclave: Where the actual function that does the procession goes and how it gets compiled

After reading lots of documentation i did the first simple enclave function:
enclave {
//Include files
//Import other edl files
//Data structure declarations to be used as parameters of the
//function prototypes in edl
trusted {
public function myFirstMethod([in] int *a, [in] int *b,[out] int *sum);
};
untrusted {
};
};
Then over bash I run the edger8r:
sgx_edger8r enclave.edl
Then it generated the following files as you can see over the schema:
So I assume somewhere over the enclave_t.c the only reference I found is in this function:
static sgx_status_t SGX_CDECL sgx_myFirstMethod(void* pms)
{
CHECK_REF_POINTER(pms, sizeof(ms_myFirstMethod_t));
ms_myFirstMethod_t* ms = SGX_CAST(ms_myFirstMethod_t*, pms);
sgx_status_t status = SGX_SUCCESS;
int* _tmp_a = ms->ms_a;
size_t _len_a = sizeof(*_tmp_a);
int* _in_a = NULL;
int* _tmp_b = ms->ms_b;
size_t _len_b = sizeof(*_tmp_b);
int* _in_b = NULL;
CHECK_UNIQUE_POINTER(_tmp_a, _len_a);
CHECK_UNIQUE_POINTER(_tmp_b, _len_b);
if (_tmp_a != NULL) {
_in_a = (int*)malloc(_len_a);
if (_in_a == NULL) {
status = SGX_ERROR_OUT_OF_MEMORY;
goto err;
}
memcpy(_in_a, _tmp_a, _len_a);
}
if (_tmp_b != NULL) {
_in_b = (int*)malloc(_len_b);
if (_in_b == NULL) {
status = SGX_ERROR_OUT_OF_MEMORY;
goto err;
}
memcpy(_in_b, _tmp_b, _len_b);
}
ms->ms_retval = myFirstMethod(_in_a, _in_b);
err:
if (_in_a) free(_in_a);
if (_in_b) free(_in_b);
return status;
}
Especially in
ms->ms_retval = myFirstMethod(_in_a, _in_b);
But where to put the myFirstMethod? Also how I will compile my enclave as a part of an application as a static library.
As fas as I searched is the tutorial in theese links:
https://software.intel.com/en-us/articles/intel-software-guard-extensions-developing-a-sample-enclave-application
https://software.intel.com/en-us/sgx/code-samples
All mention Visual Studio that does not natively run over GNU/Linux so are a bit hard for me to follow.
Edit 1:
Further looking I have seen on https://github.com/01org/linux-sgx that I can compile over simulation mode as the link mentions:
make SGX_MODE=SIM
And I successfully I have installed the driver and the sdk. I want to compile over SIMULATION mode and not real one.
The autogenerated outputs of edger8r are only to provide interface between the enclave and the untrusted outside world. They are not supposed to contain your implementations.
You should define myFirstMethod in another source file, say enclave.c or enclave.cpp and link it with the rest of your project. The signature of the function being exactly what you declared in your edl, except for the pointer qualifiers, which are for edger8r to consume.
It will go like this:
enclave.cpp:
void myFirstMethod(int *a, int *b, int *sum)
{
*sum = *a + *b;
}
Dimitris first check if you have compatible hardware from this list
https://github.com/ayeks/SGX-hardware
Then try to clone an run this repo
https://github.com/digawp/hello-enclave
That will help you understand how it works

Detecting end off a call PJSIP

I am writing an application on Ubuntu 16.04 with PJSUA/PJSIP.I need to detect when a call is hanged-up. Is there a sort off call_state() function ?
Thank you !
Found the solution here and here :
You have to modify the static void on_call_state(pjsua_call_id call_id, pjsip_event *e) function like so :
/* Callback called by the library when call's state has changed */
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
pjsua_call_info ci;
PJ_UNUSED_ARG(e);
pjsua_call_get_info(call_id, &ci);
PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
(int)ci.state_text.slen,
ci.state_text.ptr));
if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
/*YOUR CODE HERE*/
}
}

Qt: Downloading a file doesn't work

For three days now I try to come up with a workable code to simply download a file from an Url, but I had my fair share of problems so far and now I am at a point where I can't see the error.
First of all, my code:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.downloadArchive(QString("https://bitbucket.org/BattleClinic/evemon/downloads/EVEMon-binaries-1.8.1.4016.zip"), QCoreApplication::applicationDirPath(), QString("evemon.zip"));
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QFileInfo>
#include <QNetworkAccessManager>
#include <QNetworkReply>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
bool downloadArchive(QString archiveUrl, QString saveToPath, QString archiveName);
private slots:
void downloadReadyRead();
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void downloadFinished();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
QNetworkAccessManager manager;
QFile *file;
QNetworkReply *reply;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->downloadLabel->hide();
ui->downloadProgressBar->hide();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::downloadReadyRead()
{
if(file)
{
file->write(reply->readAll());
}
}
void MainWindow::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
ui->downloadProgressBar->setMaximum(bytesTotal);
ui->downloadProgressBar->setValue(bytesReceived);
}
void MainWindow::downloadFinished()
{
downloadReadyRead();
file->flush();
file->close();
if(reply->error())
{
QMessageBox::information(this, "Download failed", tr("Failed: %1").arg(reply->errorString()));
}
reply->deleteLater();
reply = NULL;
delete file;
file = NULL;
ui->downloadLabel->hide();
ui->downloadProgressBar->hide();
}
bool MainWindow::downloadArchive(QString archiveUrl, QString saveToPath, QString archiveName)
{
QUrl url(archiveUrl);
if(archiveName.count() <= 0)
{
return false;
}
if(QFile::exists(saveToPath + "/" + archiveName))
{
QFile::remove(saveToPath + "/" + archiveName);
}
file = new QFile(saveToPath + "/" + archiveName);
if(!file->open(QIODevice::WriteOnly))
{
delete file;
file = NULL;
return false;
}
reply = manager.get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
connect(reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
ui->downloadLabel->setText(QString("Downloading %1...").arg(archiveName));
ui->downloadLabel->show();
ui->downloadProgressBar->show();
return true;
}
Downloader.pro
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Downloader
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
In mainwindow.cpp I'm checking for an error and print it to a MessageBox, in case there is one. The first error I had with the current code in the reply was "Unable to init SSL Context", because I'm requesting data from a https-site. I googled a while and found the solution to be two files called "libeay32.dll" and "ssleay32.dll" I had to copy to the executable's directory.
There are now no more errors within the reply (at least the MessageBox doesn't show up)....however, after the downloadFinished Function was executed, the downloaded file has a size of 0 kb, which makes me think, their wasn't at all a download happening.
I skipped the "if(reply->error())" statement and showed the MessageBox no matter what....I got an: "Unknown Error". Should an "Unknown Error" not set the "if(reply->error())" statement to true?
There is no problem with permissions either....I tried it as Admin....so no problem at creating the file itself.
Can anyone help me to get that code working?
Do I miss any dlls or an #include?
Thanks
Download with SSL:
connect(&http, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedHttp(QNetworkReply*)));
QNetworkRequest *req = new QNetworkRequest();
req->setUrl( QUrl("https://...") );
QSslConfiguration configSsl = QSslConfiguration::defaultConfiguration();
configSsl.setProtocol(QSsl::AnyProtocol);
req->setSslConfiguration(configSsl);
http.get(*req);
You need: libeay32.dll, libssl32.dll, ssleay32.dll (from OpenSSL) and Visual c++ 2008 SP1 redist package.
Make sure that it works for a non-ssl file. Then to add ssl support, try following the directions in the answers to this question:
Qt SSL support missing
Also try using qDebug in your code instead of the QMessageBox most of the time. It makes adding debugging lines easier, and it won't interrupt your code or fill your screen with QMessageBoxes.

jni callback works for java types, but not c types

I have followed the advice at
registering java function as a callback in C function and can callback with "simple" types such as integer and string, e.g.:
jstring js = (*env)->NewStringUTF(env, "hello");
(*env)->CallStaticVoidMethod(env, cls, methodid, js);
However, if I am trying to do the same with C datatypes which have been wrapped with SWIG, I am only getting null pointers in Java. In the C part they are definitely not 0. Do they need to be treated differently?
[EDIT:]
Some more information:
As stated above, char*/string is working for me as well. I am looking for a solution for C struct's, which have been wrapped by SWIG and have been allocated in Java.
E.g.:
typedef struct {
unsigned short length;
unsigned short value;
} lv_t;
is getting wrapped by SWIG, so I can use it in Java:
lv_t lv;
lv = modulename.modulename_new_lv();
lv.setLength(1);
lv.setValue(2);
Then I will give this struct from Java to C:
modulename.send(lv);
C will send it over the network, receive some reply and change the values in lv. Now, this should give the modified lv back to Java.
void jni_call_received_hook(lv_t* lv){
JNIEnv* m_env;
(*m_vm)->AttachCurrentThread(m_vm, (void**) &m_env, NULL );
jclass cls = (*m_env)->FindClass( m_env, "gui/StateMachine" );
jmethodID mid = (*m_env)->GetStaticMethodID(m_env, cls, "callReceivedEvent", "(Lcom/something/modulename/jni/lv_t;)V");
if (mid == 0){
log(E, "Unable to find method for callback");
return;
}
// what to do here to create a jobject?
jobject lv_j = ...;
(*m_env)->CallStaticVoidMethod(m_env, cls, mid, lv_j);
}
Which calls:
public static void messageHandler(lv_t lv) {
System.out.println("messageHandler().");
System.out.println("lv " + lv);
}
Sorry but I'm not able to comment in your question yet, so this is more a comment rather than an answer. Anyway, I've recently done something like that.
My callback works and is implemented as:
void jni_call_received_hook(char* username){
JNIEnv* m_env;
(*m_vm)->AttachCurrentThread(m_vm, (void**) &m_env, NULL );
jclass cls = (*m_env)->FindClass( m_env, "gui/StateMachine" );
jmethodID mid = (*m_env)->GetStaticMethodID(m_env, cls, "callReceivedEvent", "(Ljava/lang/String;)V");
if (mid == 0){
log(E, "Unable to find method for callback");
return;
}
(*m_env)->CallStaticVoidMethod(m_env, cls, mid, (*m_env)->NewStringUTF(m_env, username));
}
The variable m_vm is an instance of the JVM I've kept upon calling a method that registered this callback, like this:
JNIEXPORT void JNICALL Java_gui_StateMachine_setCallReceivedCallback(JNIEnv *e, jobject o){
(*e)->GetJavaVM(e, &m_vm );
set_call_received_hook(jni_call_received_hook);
}
Maybe your missing something. Let me know if this isn't clear enough. Hope it helps.

Resources