How to use PERF_SAMPLE_READ with mmap - c++

This question is related to the perf_event_open syscall, but there is no tag for it.
I'm currently looking to use the PERF_SAMPLE_READ member of the enum perf_event_sample_format to retreive some data from a memory map, but for an unknown reason, the syscall itself return "invalid argument" (errno 22).
I have the following configuration :
this->eventConfiguration.sample_freq = 11;
this->eventConfiguration.freq = true;
this->eventConfiguration.inherit = true;
this->eventConfiguration.sample_type = PERF_SAMPLE_CPU | PERF_SAMPLE_TIME | PERF_SAMPLE_PERIOD /*| PERF_SAMPLE_READ*/;
The event I'm tracking is PERF_COUNT_HW_CPU_CYCLES.
There is my syscall. I spy each core of my computer :
int fileDescriptor = syscall(__NR_perf_event_open, this->configuration.getEventConfiguration() , -1, i, -1, 0);
The handling of the error is shown below, but I don't think it's useful...
if(fileDescriptor < 0) {
switch(errno) {
// here is some cases
};
}
Thanks in advance ! :-)

I've found the bug !
The problem is that the kernel don't support the use of PERF_SAMPLE_READ when the inherit member of the perf_event_attr structure is set.
The following code is from the kernel sources : https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/events/core.c#n10788
/*
* We currently do not support PERF_SAMPLE_READ on inherited events.
* See perf_output_read().
*/
if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ))
goto err_ns;

Related

linux pseudo terminal (open select read)

I have a following scenario: Someone creates a pseudo terminal via opening /dev/ptmx. New terminal is created and named for example /dev/pts/2. Then, in my program I open /dev/pts/2 for reading. But I also open other devices for reading and use select() function to wait for any incoming data. The select have also some timeout specified for performing other stuff when no data arrives for too long. After successful select i read data using read() function and then print it on the screen.
I encountered an issue if the pseudo terminal is closed by the one who created it. In this case select function ends immediately indicating success as well as read ends indicating "no data" by returning zero. The issue imho is that neither select nor read returns error in such case. How should I handle this to detect that the terminal is no longer existing?
Status processData()
{
fd_set readFileDescriptorSet; // defined somewhere else
int maxFileDescriptor; // defined somewhere else
struct timeval timeout; // defined somewhere else
int ret = select(maxFileDescriptor + 1, &readFileDescriptorSet, nullptr, nullptr, &timeout);
if (!ret) // timeout
return Status::success();
if (ret < 0) // error from select()
return Status::error("select error");
ssize_t rd;
char buff[10];
do {
rd = read(interfaces.serialPort.getFileDescriptor(), buff, sizeof(buff) - 1);
if (rd > 0) { // some data has been read
buff[rd] = '\0';
std::cout << buff;
}
} while (rd > 0);
if (rd < 0) // error from read()
return Status::error("read error");
return Status::success();
}
While the way I open the pseudo terminal is following:
Status internalOpen(std::string fileName)
{
close();
fileDescriptor = ::open(fileName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fileDescriptor == -1)
return Status::error("Terminal::internalOpen::open('" + fileName + "')");
struct termios attributes;
if (tcgetattr(fileDescriptor, &attributes))
return Status::error("Terminal::internalOpen::tcgetattr()");
setAttributes(attributes);
if (tcsetattr(fileDescriptor, TCSANOW, &attributes))
return Status::error("Terminal::internalOpen::tcsetattr()");
return Status::success();
}
void setAttributes(struct termios &attributes)
{
cfmakeraw(&attributes);
cfsetspeed(&attributes, Config::baudRate);
attributes.c_iflag &= ~(IXOFF | IXANY);
attributes.c_oflag &= ~(ONLCR);
attributes.c_lflag &= ~(ECHOE);
attributes.c_cflag &= ~(CSTOPB | CRTSCTS);
attributes.c_cflag |= CREAD | CLOCAL;
attributes.c_cc[VMIN] = 0;
attributes.c_cc[VTIME] = 0;
}
After select() returns indicating that there's something to be read, the shown code loops repeatedly trying to read() from the non-blocking file descriptor until it is 0:
do {
rd = read( ...
} while (rd > 0);
That's certainly reasonable. Except that the closed connection results in the very first read() returning 0, which the shown logic cannot discriminate.
All that's really needed here is to keep track of whether anything has been read, prior read() returning 0. But if read() returned 0 right off the bat, your goose is cooked.
Additionally, there a few other improvements will make things more robust.
After select() returns, actually check if the file descriptor's bit remains set in the readFileDescriptorSet. The shown logic simply assumes that it is, by checking for all other possibilities. Still, this is somewhat fragile. It's easy to forget this assumption if something tangentially related gets modified (i.e., another fle descriptor gets thrown into the mix).
Use poll() instead of select(), and explicitly check for POLLHUP|POLLRDHUP in revents. The file descriptor closure condition is more explicitly called out, in the poll() interface.

libnl/nl80211 equivalent of iw_set_ext

I started writing a code to handle wifi card using iwconfig/ioctl when I realised that it is depricated and most of applications uses nl80211.
I started reading its source code but there is no docs and code is a bit complicated.
How can I do simple things like scanning, turning off/on, setting card mode using nl80211 or libnl?
This is what I started with iw:
void set_card_mode(MODE mode, std::string ifname)
{
int skfd = iw_sockets_open();
struct iwreq wrq;
wrq.u.mode = static_cast<unsigned int>(mode);
power_interface(ifname, false);
if(iw_set_ext(skfd, ifname.c_str(), SIOCSIWMODE, &wrq) < 0)
throw std::runtime_error("Can set card mode");
}
MODE get_card_mode(std::string ifname)
{
int skfd = iw_sockets_open();
struct iwreq wrq;
if (iw_get_ext (skfd, ifname.c_str(), SIOCGIWMODE, &wrq) >= 0)
{
return static_cast<MODE>(wrq.u.mode);
}
}
Is there any equivalent of iw_get_ext to set/get wifi interface or any api with simple functions like "set_mode" or "power_off"?
I scan with netlink using the following steps
Prepare and execute NL80211_CMD_TRIGGER_SCAN
Prepare and execute NL80211_CMD_GET_SCAN
Together with NL80211_CMD_GET_SCAN a callback is registered.
In the callback the raw data are parsed as BSS. The IE's are parsed to. See enums with NL80211_BSS_MAX, NL80211_ATTR_MAX from nl80211.h.
Check the return values of every netlink call before process the next step.
Code snippets:
nl_sock* socket = nl_socket_alloc();
genl_connect(socket);
struct nl_msg* msg = nlmsg_alloc();
int driverId = genl_ctrl_resolve(socket, "nl80211");
genlmsg_put(msg, 0, 0, driverId, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
and fetch with:
genlmsg_put(msg, 0, 0, driverId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);
nl_socket_modify_cb(socket, NL_CB_VALID, NL_CB_CUSTOM, onScanResult, null);
My callback starts with:
struct genlmsghdr* msgHeader = (genlmsghdr*)nlmsg_data(nlmsg_hdr(msg));
struct nlattr* attributes[NL80211_ATTR_MAX + 1];
struct nlattr* bss[NL80211_BSS_MAX + 1];
if(nla_parse(attributes, NL80211_ATTR_MAX, genlmsg_attrdata(msgHeader, 0), genlmsg_attrlen(msgHeader, 0), NULL) == 0)
{
// Read the attributes
// and check for NL80211_ATTR_BSS != 0
}
Most of the scanning results did I found in NL80211_BSS_INFORMATION_ELEMENTS.
if (nla_parse_nested(bss, NL80211_BSS_MAX, attributes[NL80211_ATTR_BSS], bss_policy) == 0)
{ /* read the bss attributes */ }
See NL80211_BSS_INFORMATION_ELEMENTS from nl80211.h and
But I failed to check for WEP privacy.
To check for WPA or WPA2 is easy, because there is an extra IE element with ID 48 (Śee IEEE Std 802.11 2012, chapter 8.4.2, free download form ieee side)

How come GetDefaultCommConfig fails on windows 10

I use the following code to verify that a serial port name is valid on the computer:
typedef std::pair<StrAsc const, bool> port_pair_type;
typedef std::list<port_pair_type> port_pairs_type;
port_pairs_type pairs;
StrBin config_buffer;
config_buffer.fill(0,sizeof(COMMCONFIG));
while(!pairs.empty())
{
port_pair_type pair(pairs.front());
pairs.pop_front();
if(!pair.second)
{
// we need to get the default configuration for the port. This may
// require some fudging on the buffer size. That is why two calls
// are being made.
uint4 config_size = config_buffer.length();
StrUni temp(pair.first);
COMMCONFIG *config(reinterpret_cast<COMMCONFIG *>(config_buffer.getContents_writable()));
config->dwSize = sizeof(COMMCONFIG);
rcd = GetDefaultCommConfigW(
temp.c_str(), config, &config_size);
if(!rcd && config_buffer.length() < config_size)
{
config_buffer.fill(0, config_size);
config = reinterpret_cast<COMMCONFIG *>(config_buffer.getContents_writable());
config->dwSize = sizeof(COMMCONFIG);
rcd = GetDefaultCommConfigW(
temp.c_str(),
reinterpret_cast<COMMCONFIG *>(config_buffer.getContents_writable()),
&config_size);
}
// if the call succeeded, we can go ahead and look at the
// configuration structure.
if(rcd)
{
COMMCONFIG const *config = reinterpret_cast<COMMCONFIG const *>(
config_buffer.getContents());
if(config->dwProviderSubType == PST_RS232)
port_names.push_back(pair.first);
}
else
{
OsException error("GetDefaultCommConfig Failed");
trace("\"%s\"", error.what());
}
}
else
port_names.push_back(pair.first);
}
On windows 10, when trying to confirm a serial port that uses usbser.sys, the call to GetDefaultCommConfig() is failing and the error code returned by GetLastError() is 87 (invalid parameter). As I am aware, the usbser.sys driver has been rewritten on windows 10 and I suspect that this is a problem with that driver. Does anyone else have an idea of what might be going wrong?
This had been a bug in usbser.sys and was fixed with the Windows 10 Update KB3124262 from 27.01.2016.
The Microsoft employee explained:
The COM port name in the HKLM\HARDWARE\DEVICEMAP\SERIALCOMM registry is not NULL terminated.
Related discussion on MSDN
Because of Windows 10's update policies this issue should not appear in the future anymore.
When you call GetDefaultCommConfigW the second time you probably need to config->dwSize to the new size the structure. Eg:
config->dwSize = config_size;

writing and reading to/from a serial port with a timeout in c++ and Linux

I'm trying to send some hex string to a serial port, and directly read its answer in c++. If there is no answer it should timeout after a given period of time.
What is the simplest implementation of such a task?
Do i need to use stuff like boost?
To be clear: I'm searching for the most simple way to achieve this.
Sorry if my question is dumb, but im new to this topic, thanks in advance!
EDIT: Sorry that I forgot to mention, it should run on Linux.
this should be similar to your declaration:
Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
Setup(CSerial::EBaudrate(9600),
CSerial::EDataBits(8),
CSerial::EParity(NOPARITY),
CSerial::EStopBits(ONESTOPBIT));
Reading data:
// Read data, until there is nothing left
DWORD dwBytesRead = 0;
BYTE abBuffer[100];
do
{
// Read data from the COM-port
serial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
if (dwBytesRead > 0)
{
// TODO: Process the data
}
}
while (dwBytesRead == sizeof(abBuffer));
More details can be found here on code project: http://www.codeproject.com/Articles/992/Serial-library-for-C
Please note: I am used to programming serial ports in c#, and so (to the best of my knowledge) believe this would work for you. (I would also like to point outall serial port communication is send actually through as hex, but may be read via the buffer as a decimal value ( please refer to http://www.asciitable.com/ for converstion, or use something similar to UTF8 encoding)
EDIT - As per comment;
Please refer to : http://msdn.microsoft.com/en-gb/library/windows/hardware/hh439614(v=vs.85).aspx for details on serial port read/write timeouts
Write timeout will be similar to;
[BrowsableAttribute(true)]
public:
property int WriteTimeout {
int get ();
void set (int value);
}
Which allows you to get or set the timeout attribute
Full Program
public:
static void Main()
{
String^ name;
String^ message;
StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
Thread^ readThread = gcnew Thread(gcnew ThreadStart(PortChat::Read));
// Create a new SerialPort object with default settings.
_serialPort = gcnew SerialPort();
// Allow the user to set the appropriate properties.
_serialPort->PortName = SetPortName(_serialPort->PortName);
_serialPort->BaudRate = SetPortBaudRate(_serialPort->BaudRate);
_serialPort->Parity = SetPortParity(_serialPort->Parity);
_serialPort->DataBits = SetPortDataBits(_serialPort->DataBits);
_serialPort->StopBits = SetPortStopBits(_serialPort->StopBits);
_serialPort->Handshake = SetPortHandshake(_serialPort->Handshake);
// Set the read/write timeouts
_serialPort->ReadTimeout = 500;
_serialPort->WriteTimeout = 500;
_serialPort->Open();
_continue = true;
readThread->Start();
Console::Write("Name: ");
name = Console::ReadLine();
Console::WriteLine("Type QUIT to exit");
while (_continue)
{
message = Console::ReadLine();
if (stringComparer->Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort->WriteLine(
String::Format("<{0}>: {1}", name, message) );
}
}
readThread->Join();
_serialPort->Close();
}
static void Read()
{
while (_continue)
{
try
{
String^ message = _serialPort->ReadLine();
Console::WriteLine(message);
}
catch (TimeoutException ^) { }
}
}
EDIT 2
Please refer to Linux Serial Port: Blocking Read with Timeout where this has been declared in the question and some of the answers may prove useful to you as well! :)
I recently came for the same issue and I found a good solution using select()
Read the documentation here: manpages.courirer-mta.org/htmlman2/select2.html
In your case you need to setup the timeout, which is the 5th argument of select:
struct timeval timeout;
timeout.tv_sec = 0 ; // seconds
timeout.tv_usec = 1000 ; // microseconds
Hope this helps.

How to programatically get uid from pid in osx using c++?

Given a pid, I want to find the owner of the process (as uid). Is there a way to get this in osx (or any unix) using C++?
Google didn't help. 'ps' is able to do it; so I assume there should be a way to get it programatically.
Solution from Indhu helped me on my way, so I would like to post my own.
UID from PID with pure C:
#include <sys/sysctl.h>
uid_t uidFromPid(pid_t pid)
{
uid_t uid = -1;
struct kinfo_proc process;
size_t procBufferSize = sizeof(process);
// Compose search path for sysctl. Here you can specify PID directly.
const u_int pathLenth = 4;
int path[pathLenth] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
int sysctlResult = sysctl(path, pathLenth, &process, &procBufferSize, NULL, 0);
// If sysctl did not fail and process with PID available - take UID.
if ((sysctlResult == 0) && (procBufferSize != 0))
{
uid = process.kp_eproc.e_ucred.cr_uid;
}
return uid;
}
No excess allocation, no loops.
The source for the ps command, reveals that there is a function called get_proc_stats defined in proc/readproc.h that (among other things) returns the real user name(UID) & Effective user name(EUID) for a given pid.
You need to do install libproc-dev to get this function. and then you can do:
#include <proc/readproc.h>
void printppid(pid_t pid)
{
proc_t process_info;
get_proc_stats(pid, &process_info);
printf("Real user of the process[%d] is [%s]\n", pid, process_info.ruser);
}
compile it with gcc the-file.c -lproc.
Once you have the real user name you can use getpwnam() and getgrnam() functions to get the uid.
You could look at how ps does it. It looks like it uses the kvm_getprocs function.
However, it's much more portable (you said "any unix", but e.g. the Linux and Solaris way is to look in the /proc filesystem - and other unixes may have different APIs) to just parse the output of ps (ps -o user= -p (pid) for example, to eliminate any extraneous output) than to do any system-specific process stuff
There's not a portable way to do this. On Mac OS, you've got to use poorly documented sysctl interfaces: see this previous stackoverflow question. (As other commenters pointed out, on Linux you can use proc. On FreeBSD, you should be able to use kvm_getfiles, although this is not available on Mac OS.)
Your best bet is to use the source for Apple's ps as a jumping-off point for grabbing process data and then you'll be able to use getpwuid(3) once you have the uid.
Finally found a way to programatically do this without parsing the output of 'ps'
uint getUidUsingSysctl(uint pid)
{
struct kinfo_proc *sProcesses = NULL, *sNewProcesses;
int aiNames[4];
size_t iNamesLength;
int i, iRetCode, iNumProcs;
size_t iSize;
iSize = 0;
aiNames[0] = CTL_KERN;
aiNames[1] = KERN_PROC;
aiNames[2] = KERN_PROC_ALL;
aiNames[3] = 0;
iNamesLength = 3;
iRetCode = sysctl(aiNames, iNamesLength, NULL, &iSize, NULL, 0);
/* allocate memory and populate info in the processes structure */
do
{
iSize += iSize / 10;
sNewProcesses = (kinfo_proc *)realloc(sProcesses, iSize);
if (sNewProcesses == 0)
{
if (sProcesses)
free(sProcesses);
/* could not realloc memory, just return */
return -1;
}
sProcesses = sNewProcesses;
iRetCode = sysctl(aiNames, iNamesLength, sProcesses, &iSize, NULL, 0);
} while (iRetCode == -1 && errno == ENOMEM);
iNumProcs = iSize / sizeof(struct kinfo_proc);
for (i = 0; i < iNumProcs; i++)
{
if (sProcesses[i].kp_proc.p_pid == pid)
{
return sProcesses[i].kp_eproc.e_ucred.cr_uid;
}
}
/* clean up and return to the caller */
free(sProcesses);
return -1;
}
Note: There might be a better way to get 'kinfo_proc' instead of iterating through all process.