I'm trying to write a simple fingerprint scanning program in c++ using libfprint, however it intermittently segfaults when run. Valgrind says the error is in the call to fp_enroll_finger which is consistent with my debugging, however beyond that I have absolutely no idea what is causing this error. Some of the times the program is run its fine, but some times it seems to consistently segfault for a period of time whenever the program is run?
Heres the code:
#include <iostream>
extern "C"
{
#include <libfprint/fprint.h>
}
using namespace std;
fp_dev * fpdev;
fp_print_data ** fpdata;
bool createDevice();
int main(int argc, char **argv)
{
int r = fp_init();
if(r != 0)
{
return r;
}
while(createDevice())
{
cout << "Scan right index finger" << endl;
int enrollStatus = fp_enroll_finger(fpdev, fpdata);
if(enrollStatus != 1)
{
cout << "Bad scan" << endl;
fp_dev_close(fpdev);
}
else
{
cout << "Good scan" << endl;
fp_print_data_save(fpdata[0], RIGHT_INDEX);
break;
}
}
if(fpdev != NULL)
{
fp_dev_close(fpdev);
}
fp_exit();
return 0;
}
bool createDevice()
{
fp_dscv_dev ** listOfDiscoveredDevs;
fp_dscv_dev * discoveredDevice;
listOfDiscoveredDevs = fp_discover_devs();
discoveredDevice = listOfDiscoveredDevs[0];
if(discoveredDevice != NULL)
{
cout << "Device found" << endl;
fpdev = fp_dev_open(discoveredDevice);
}
else
{
cout << "No device found" << endl;
return false;
}
fp_dscv_devs_free(listOfDiscoveredDevs);
return true;
}
You need to define fpdev and fpdata as:
fp_dev * fpdev;
fp_print_data * fpdata;
And use them as:
fp_enroll_finger(&fpdev, &fpdata);
Also don't forget to free fpdata when you no longer need it with fp_print_data_free
fp_dev * fpdev;
fp_print_data ** fpdata;
Will create 2 uninitialised pointers pointing to random memory location and leading to segfault once fp_enroll_finger will attempt to acces that location.
Checking fp_enroll_finger return value can be useful as well.
Related
I was trying to apply an iteration to my leveldb file, but unfortunately I couldn't get the result. The problem that I'm facing is a segmentation fault in using the pointer of the iterator. I used gdb And I got that the problem is in the line
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
(I added before some values to this file /tem/userDb , and the add is working good .)
#include <assert.h>
#include <leveldb/db.h>
#include <iostream>
#include <sstream>
using namespace std;
void iteration(leveldb::DB* db)
{
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next())
{
cout << "key :" << it->key().ToString() << " : "
<< "value:" << it - > value().ToString() << endl;
}
if (false == it->status().ok())
{
cerr << "An error was found during the scan" << endl;
cerr << it->status().ToString() << endl;
}
delete it;
}
int main(int argc, char *argv[])
{
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
// erase error if the database exists
options.error_if_exists = true;
leveldb::Status s = leveldb::DB::Open(options, "/tmp/userDb", &db);
if (!s.ok())
cerr << s.ToString() << endl;
iteration(db);
delete db;
}
Not familiar with the leveldb API, but you're using db regardless of whether s.ok() is true or false. I'd assume that if s.ok() is false, db is either NULL, or in a state such that iteration or other operations won't work.
You should change the code to:
if (!s.ok()) {
cerr << s.ToString() << endl;
return -1;
}
I'm trying to exchange messages using multiple covert channels.
So, basically, first i need to select the channel that i want to use for communication and then select the "destination_ip" of the user that i want to chat with and after that the
processMessage()
is called. Now, to move from one channel to another I have to close the existing connection and then open a new connection with the new channel that i want to use. My code below is modified to keep using the same channel after closing the connection and contain only the things that you need.
#include <channelmanager.hpp>
#include <thread>
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <openssl/hmac.h>
struct CommunicationFixture {
CommunicationFixture() {
channelmanager.setErrorStream(&cout);
channelmanager.setOutputStream(&cout);
destination_ip = "";
channel_id = channelmanager.getChannelIDs()[0];
}
library::ChannelManager channelmanager;
vector<string> last_adapters;
string destination_ip;
string channel_id = "";
int processMessage(string message) {
if (message.compare("exit") == 0) {
channelmanager.closeConnection(destination_ip);
return 1;
}
vector<string> arguments;
boost::split(arguments, message, boost::is_any_of(" "), boost::token_compress_on);
if (arguments[0].compare("argument") == 0) {
if (arguments.size() < 2) {
cout << "Not enough arguments" << endl;
return 0;
}
string argument_list = arguments[1];
for (unsigned int i = 2; i < arguments.size(); i++) {
argument_list += " " + arguments[i];
}
channelmanager.setChannelArguments(destination_ip, argument_list);
cout << "Set channel argument to '" << argument_list << "'." << endl;
return 0;
}
if (message.compare("help") == 0) {
cout << "Help not available in chat mode. Close chat first with 'exit'" << endl;
return 0;
}
channelmanager.openConnection(destination_ip, channel_id);
channelmanager.sendMessage(destination_ip, message);
return 0;
}
int close(string destination){
cout << "closing.." << endl;
channelmanager.closeConnection(destination); //I believe i have the error because of this!
return 0;
}
};
BOOST_FIXTURE_TEST_SUITE(communication, CommunicationFixture)
BOOST_AUTO_TEST_CASE(basic_communication) {
selectAdapterId(0);
cout << "Test" << endl << endl;
printCommands();
cout << "Enter your command:" << endl;
string command;
int code = 0;
while (code != 2) {
std::getline(cin, command);
code = processCommand(command);
if (code == 1) {
// chat
cout << "chat started.." << endl;
int chatCode = 0;
while (chatCode != 1) {
std::getline(cin, message);
close(destination_ip);
chatCode = processMessage(message);
channelmanager.setErrorStream(&cout);
}
cout << "chat ended." << endl;
}
}
}
BOOST_AUTO_TEST_SUITE_END()
Note that, i think that the error happens due to the
function close()
because without it i don't get any errors. and the error doesn't happen immediately but after exchanging some messages. Here's the error:
unknown location(0): fatal error: in
"communication/basic_communication": memory access violation at
address: 0x00000024: no mapping at fault address
communicationTest.cpp(325): last checkpoint: "basic_communication"
test entry
Memory access violation happen when you are trying to access to an unitialized variable, in this case the channelmanager.
I can only see that you initialize channelmanager in the processMessage() method and you are closing the connection before initializing the channelmanager as it happen in:
close(destination_ip);
chatCode = processMessage(message);
Either you change the initialization or do not close it before the processMessage() method.
Memory access violation is also called a segmentation fault (or segfault), occurs when the program tries to access a memory location that doesn't exist, or is otherwise inaccessible. We call this trying to access an illegal memory location. That memory is either non-existent or we aren't aren't allowed to touch it.
If the first input from user is 'exit', which is going to call
if (message.compare("exit") == 0) {
channelmanager.closeConnection(destination_ip);
return 1;
}
In this case, destination_ip isn't initialised.
EDIT: I started from scratch, going with a user+pass authentication for better security.
I posted a new question here.
I'm writing a program that checks that the computer running it has a specific hostname (as an authentication method).
#include <iostream>
using namespace std;
void RUN()
{
//Do stuff
}
char const* HOSTNAME
int auth()
{
if (HOSTNAME = getenv("HOSTNAME"))
{
HOSTNAME = getenv("HOSTNAME");
return 0;
}
else if(HOSTNAME = getenv("COMPUTERNAME"))
{
HOSTNAME = getenv("COMPUTERNAME");
return 0;
}
else
{
return 1;
};
}
int main()
{
cout << "Authenticating..." << endl; auth();
if (HOSTNAME == "Craptop")
{
cout << "Success!" << endl;
RUN();
}
else
{
cout <<
cout << "Authentication failed! Exiting..." << endl;
exit(0);
};
return 0;
}
Im getting this error: (should be the initializer but seams to act like a variable)
./EX_host_locked.cpp:5:1: error: expected initializer before ‘int’
int auth()
^~~
since int acts like a variable, auth is uninitialized and causing more errors later.
How can I make int be the initializer for auth? Also how could I generally improve my code (for security/stability)?
You are missing ; after line following line:
char const* HOSTNAME
So you are getting the error. Put ; and make it:
char const* HOSTNAME;
I've met some problem in debug some code in vs2013/2015/2008.
#include <iostream>
using namespace std;
int main()
{
int mode = 1;
int size = 1;
if (mode == 0)
{
cout << "mode = 0" << endl;
}
else
{
if (mode == 1)
{
if (size > 0)
{
cout << "mode=1,size=1" << endl; //in debug mode will execute this sentence
}
else
return 0; //however,when I Step in (F10),this will also be executed but have no influence.But When I insert a breakpoint in there and press F5, will not break in there
}
else if (mode == 2)
{
if (size > 0)
{
cout << "mode=2,size=1" << endl;
}
else
return 0;
}
}
return 1;}
So, how to explain this phenomenon? Does it have any problem? And how can I solve it?
This is how the debugger works in VS 2015. Ignore it.
return 0; isn't executed, even if it looks like it. Weird behavior, I was surprised by that too.
They should have made the arrow go to the else statement, not the first line after it, but for some reason they didn't.
Just ignore it. You can make a feature request if you want too :)
I've made three files using Visual C++ 2008 express for a text based RPG game. Before I really dive into the whole thing I want to get the basics ironed out: new game, save game, continue game, quit game. So far I have the make a character section (in this case find a weapon) and quit game all ironed out. I'm stuck on how to pass the weapon stats from a struct to a save file. I appear to pass the members of the struct without issue and check the file to find "junk": Ì and -858993460 in place of my values.
How should I go about fixing my save_game and continue_game functions? I've done a lot of research trying to figure this out and nothing I've tried seems to help.
Here's the important pieces of the code:
struct player_character
{
char type;
int damage;
int stability;
};
void save_game(player_character& pc, ofstream &save);
void continue_game(player_character& pc, ifstream &get);
int main()
{
player_character pc;
ofstream save;
ifstream get;
//rest of main() goes here.
//pause screen
system("pause");
return 0;
}
//rest of functions go here.
void save_game(player_character &pc, ofstream &save_data)
{
save_data.open ("save.dat", ios::binary);
if (save_data.is_open())
{
save_data << "pc.type = " << pc.type << endl;
save_data << "pc.damage = " << pc.damage << endl;
save_data << "pc.stability = " << pc.stability << endl;
//doesn't work
//save_data.write(reinterpret_cast<char*>(&pc), sizeof(pc));
save_data.close();
}
else
{
cout << " Error. Unable to open file.";
}
}
void continue_game(player_character &pc, ifstream &get_data)
{
get_data.open("save.dat");
if (get_data.is_open())
{
//doesn't work
//get.read(reinterpret_cast<char*>(&pc), sizeof(pc));
get.close();
}
else
{
cout << " Error. Unable to open file.";
}
}
Thanks for the reponse. I'm trying the following revisions. The continue_game function appears to work. I recieve no errors (yet). When I select save after making a character I recieve the following error: Unhandled exception at 0x69197a28 in Undone.exe: 0xC0000005: Access violation reading location 0xffffffcc.
Google shows it as some sort of Windows issue.
Why is my function causing this error?
void save_game(ofstream &save, player_character const &pc)
{
save.open ("save.dat");
if (save.is_open())
{
save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type);
save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage);
save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability);
save.close();
}
else
{
cout << " Error. Unable to open file.";
}
}
int continue_game(ifstream &get)
{
if (!get.read(reinterpret_cast<char *>(&pc.type), sizeof pc.type)) { /* error */ }
if (!get.read(reinterpret_cast<char *>(&pc.damage), sizeof pc.damage)) { /* error */ }
if (!get.read(reinterpret_cast<char *>(&pc.stability), sizeof pc.stability)) { /* error */ }
return pc.type;
return pc.damage;
return pc.stability;
}
I've changed the save_game and continue_game code and included it here. I also collected the debugger and autos output (small version of autos, not all seven pages). Apparently my values are not being evaluated in save_game so continue_game has nothing to work with and doesn't cause errors.
Here's the code and debugger/autos printouts:
int save_game(ofstream &save, player_character& pc)
{
save.open ("save.dat", ios::binary);
if (save.is_open())
{
//the error hits here:
save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type);
save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage);
save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability);
save.close();
}
else
{
cout << " Error. Unable to open file.";
}
return pc.type;
return pc.damage;
return pc.stability;
}
int continue_game(ifstream &get, player_character& pc)
{
get.open ("save.dat", ios::binary);
if (get.is_open())
{
if (!get.read(reinterpret_cast<char *>(&pc.type), sizeof pc.type)) { /* error */ }
if (!get.read(reinterpret_cast<char *>(&pc.damage), sizeof pc.damage)) { /* error */ }
if (!get.read(reinterpret_cast<char *>(&pc.stability), sizeof pc.stability)) { /* error */ }
get.close();
}
else
{
cout << " Error. Unable to open file.";
}
return pc.type;
return pc.damage;
return pc.stability;
}
Debugger Output Window:
First-chance exception at 0x644e7a28 in Undone.exe: 0xC0000005: Access violation reading location 0xffffffcc.
Unhandled exception at 0x644e7a28 in Undone.exe: 0xC0000005: Access violation reading location 0xffffffcc.
Autos:
- pc {type='Ì' damage=-858993460 stability=-858993460 } player_character &
type -52 'Ì' char
damage -858993460 int
stability -858993460 int
pc.type -52 'Ì' char
- save {_Filebuffer={...} } std::basic_ofstream > &
+ std::basic_ostream > {...} std::basic_ostream >
+ _Filebuffer {_Pcvt=0x00000000 _Mychar='Ì' _Wrotesome=false ...} std::basic_filebuf >
Well I'vve managed to make some progress. I discovered I needed to place arguments into my main_menu function (mind you I'm not taking about the main() function, but one I made) so that they would be passed on to my save_game function. I was also able to stop the access error by adding an & into my write function.
So this:
save.write(reinterpret_cast<char const *>(&pc.type), sizeof pc.type);
save.write(reinterpret_cast<char const *>(&pc.damage), sizeof pc.damage);
save.write(reinterpret_cast<char const *>(&pc.stability), sizeof pc.stability);
instead of:
save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type);
save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage);
save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability);
The savve_game code still doesn't work properly yet when it comes to putting data into a file but it does printout to the screen.
You have to read and write each primitive data type, one by one, and use unformatted I/O only. Example:
void serialize(std::ostream & o, Player const & p)
{
o.write(reinterpret_cast<char const *>(p.type), sizeof p.type);
o.write(reinterpret_cast<char const *>(p.damage), sizeof p.damage);
o.write(reinterpret_cast<char const *>(p.stability), sizeof p.stability);
}
Player deserialize(std::istream & i)
{
Player p;
char pt;
int pd, ps;
if (!i.read(reinterpret_cast<char *>(&pt), sizeof pt)) { /* error */ }
if (!i.read(reinterpret_cast<char *>(&pd), sizeof pd)) { /* error */ }
if (!i.read(reinterpret_cast<char *>(&ps), sizeof ps)) { /* error */ }
p.type = pt; p.damage = pd; p.stability = ps;
return p;
}
Follow-up to the previous answer and edited question.
Judging by your continue_game signature,
int continue_game(ifstream &get)
pc must be some form of global struct that holds the character you're trying to resume. If pc is allocated at run-time, then you are using it incorrectly.
When you do this:
return pc.type;
return pc.damage;
return pc.stability;
A function can only have one return-type; only pc.type would be returned. This is not the cause of the error, but rather a design flaw you should be aware of.
Your initial approach to continue_game, wherein you passed in the relevant struct as a parameter,
void continue_game(player_character &pc, ifstream &get_data)
was a much better idea. I believe that if you combine the two you will find yourself without the error.
If the error continues, please use a debugger and paste the line. In addition, I can provide a sample of the code I described if you wish me to.
It looks like I figured it out! Here's what I've come up with: struct in array...and it appears to work just fine.
void save_game(fstream& file, player_type& pc)
{
file.open("save.dat");
if (file.is_open())
for (int i = 0; i < 1; i++)
{
file << pc.w_name << endl;
file << pc.d_rate << endl;
file << pc.s_rate << endl;
file.close();
}
else
cout << " Error. Unable to open file.";
menu(pc);
}//end save function
void continue_game(fstream& file, player_type player[])
{
file.open("save.dat");
if (file.is_open())
for (int i = 0; i < 1; i++)
{
file >> player[i].w_name;
file >> player[i].d_rate;
file >> player[i].s_rate;
file.close();
}
else
cout << " Error. Unable to open file.";
for (int i = 0; i < 1; i++)
{
cout << "You are continuing the game with the following weapon: " << player[i].w_name << endl;
cout << "Which has a damage rating of " << player[i].d_rate << " and a stability rating of " << player[i].s_rate << endl;
}
cout << endl;
menu(pc);
}//end continue_game