gdb cannot break in main (Cannot access memory) of libusb program? - c

(I have completely rewritten this question, as I have a minimal example now; see in history how original post looked like)
Consider this libusb program, which I compile under MINGW64 (part of MSYS2, which is updated as of today) on Windows 10 (also with latest updates as of today):
libusb-test.c
// build under MINGW64 on Windows with (assuming mingw64/mingw-w64-x86_64-libusb 1.0.26-1 installed):
// gcc -Wall -g -I/mingw64/include/libusb-1.0 libusb-test.c -o libusb-test.exe -lusb-1.0
#include <inttypes.h> //PRIu64
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "libusb.h"
int main(int argc, char *argv[]) {
libusb_device **devs;
ssize_t cnt;
int r=0, i;
struct libusb_device_descriptor desc;
r = libusb_init(NULL);
if (r < 0) {
printf("error: Cannot libusb_init, exiting\r\n");
return r;
}
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0) {
printf("error: Cannot libusb_get_device_list (Failed to enumerate USB devices), exiting\r\n");
libusb_exit(NULL);
return 1;
}
for (i = 0; devs[i]; i++) { // or: for (libusb_device **dev = devs; *dev; dev++)
libusb_device *dev = devs[i];
libusb_device_handle *handle = NULL;
printf("Trying device %d: %p\r\n", i, dev);
int ret = libusb_get_device_descriptor(dev, &desc);
if (ret) {
printf(" Failed to read device %d descriptor (%d)\r\n", i, ret);
} else {
ret = libusb_open(dev, &handle);
if (ret) {
printf(" Failed to open device %d (%d)\r\n", i, ret);
} else {
printf( " device %d open ( handle %p )\r\n", i, handle);
}
if (handle) {
libusb_close(handle);
handle = NULL;
}
}
} // end for
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
printf("Program finished; exiting.");
return r;
}
The program, after compiling, actually seems to run fine:
$ ./libusb-test.exe
Trying device 0: 000001eeb9321890
Failed to open device 0 (-5)
Trying device 1: 000001eeb9320c30
device 1 open ( handle 000001eeb93242e0 )
...
Trying device 12: 000001eeb9322640
device 12 open ( handle 000001eeb93242e0 )
Trying device 13: 000001eeb7a7bc50
Failed to open device 13 (-12)
Program finished; exiting.
... however, if I try to debug with gdb by breaking into main - it fails with "Cannot insert breakpoint":
$ gdb --args ./libusb-test.exe
GNU gdb (GDB) 12.1
...
Reading symbols from ./libusb-test.exe...
(gdb) b main
Breakpoint 1 at 0x140001593: file libusb-test.c, line 11.
(gdb) r
Starting program: C:\msys64\tmp\libusb-test.exe
[New Thread 20144.0x24c0]
[New Thread 20144.0x436c]
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x140001584
Command aborted.
(gdb)
Why does this happen - and how can I get gdb to break into this program?

Related

Printing to stdout returning gibbersih

I am using gcc 10.1.1 on Fedora 32.
The following program is to read from a file given by the user and print it into stdout. The code is an example in Modern C by Jens Gusdets.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
enum { buf_max = 32,};
int main(int argc, char* argv[argc +1]){
int ret = EXIT_FAILURE;
char buffer[buf_max] = {0};
for(int i = 0; i<argc ; ++i){
FILE* instream = fopen(argv[i] , "r");
if(instream){
while(fgets(buffer , buf_max , instream)){
fputs(buffer, stdout);
}
fclose(instream);
ret = EXIT_SUCCESS;
} else{
fprintf(stderr, "Could not open %s: ", argv[i]);
perror(0);
errno = 0;
}
}
return ret;
}
But when I run the program it is printing some gibberish like :
$ ./read some.txt
ELFDib64/ld-linux-x86-64.so.2Co.6locationderrGLIBC_2.2.5###/��^H��H���PTI��##H=X##�H��H�H��t�f.��z������UH��H��#�}�H�u��E����`..��������ATA��UH�-T+t1��u�H�[]A\A]A^A_�ff.������A�C
G#n8A0A(B BB���oGCC: (GNU) 10.1.1 20200507 (Red Hat 10.1.1-1)�#�#�#�#�#�#�#�#1�# gcc 10.1.1 2020050730k_clashectionYSSERTIONSGA!stack_realign�# gcc 10.1.1 2020050730k_cl#Z�##nux/10/../../../../lib64/crt1.oc_endbin_init.c_end.hott.c.unlikelyd.unlikelytupinit.c_end.exit_reloc.cc_endothotikelynd.unlikelyoc.c.startuploc.c_end.startupic_reloc.c.exit_reloc.c_end.exitrelocate_static_pie.startbin__dl_relocate_static_pie.endsed.0_array_entrye_dummy_init_array_entry__FRAME_END___DYNAMICNU_EH_FRAME_HDRTABLE_location##GLIBC_2.2.5LIBC_2.2.5_2.2.5c_start_main##GLIBC_2.2.5##GLIBC_2.2.5ntf##GLIBC_2.2.5libc_csu_initic_pieGLIBC_2.2.55nterpABI-tagtr.rela.dynh_framebsstesuh #�?#0yey my c program worked.
some.txt = yey my c program worked.
argv[0] is always the program name. You're printing the contents of your executable in addition to any extra files identified by the filenames passed in the arguments by starting your for loop at i = 0.
If you start at i = 1, it will exclude your executable.

main doesn't continue after call pthread_join function

I'm new to pthread and multithreading, i have written a code like that.
#include <pthread.h>
#include <unistd.h>
void *nfc_read(void *arg)
{
int fd = -1;
int ret;
uint8_t read_data[24];
while(1){
ret = read_block(fd, 8, read_data);
if(!ret){
return (void)read_data;
}
}
}
int main(int argc, char *argv[])
{
pthread_t my_thread;
void *returnValue;
pthread_create(&my_thread, NULL, nfc_read, NULL);
pthread_join(my_thread, &returnValue);
printf("NFC card value is : %s \n", (char)returnValue);
printf("other process");
return 0;
}
Until the return value from nfc_read function, as I will have other code I need to run and I don't want to block in main. How can i do that?
This is a sample where a read thread runs concurrently to the "main" thread which is doing other work (in this case, printing dots and sleeping).
To keep things simple, a simulated the reading from an input device with copying a constant string character by character. I guess, this is reasonable as the synchronization of threads is focused.
For the synchronization of threads, I used atomic_bool with atomic_store() and atomic_load() which are provided by the Atomic Library (since C11).
My sample application test-concurrent-read.c:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdatomic.h>
#include <unistd.h>
/* sampe input */
const char sampleInput[]
= "This is sample input which is consumed as if it was read from"
" a (very slow) external device.";
atomic_bool readDone = ATOMIC_VAR_INIT(0);
void* threadRead(void *pArg)
{
char **pPBuffer = (char**)pArg;
size_t len = 0, size = 0;
int c; const char *pRead;
for (pRead = sampleInput; (c = *pRead++) > 0; sleep(1)) {
if (len + 1 >= size) {
if (!(*pPBuffer = realloc(*pPBuffer, (size + 64) * sizeof(char)))) {
fprintf(stderr, "ERROR! Allocation failed!\n");
break;
}
size += 64;
}
(*pPBuffer)[len++] = c; (*pPBuffer)[len] = '\0';
}
atomic_store(&readDone, 1);
return NULL;
}
int main()
{
/* start thread to read concurrently */
printf("Starting thread...\n");
pthread_t idThreadRead; /* thread ID for read thread */
char *pBuffer = NULL; /* pointer to return buffer from thread */
if (pthread_create(&idThreadRead, NULL, &threadRead, &pBuffer)) {
fprintf(stderr, "ERROR: Failed to start read thread!\n");
return -1;
}
/* start main loop */
printf("Starting main loop...\n");
do {
putchar('.'); fflush(stdout);
sleep(1);
} while (!atomic_load(&readDone));
putchar('\n');
void *ret;
pthread_join(idThreadRead, &ret);
/* after sync */
printf("\nReceived: '%s'\n", pBuffer ? pBuffer : "<NULL>");
free(pBuffer);
/* done */
return 0;
}
Compiled and tested with gcc in cygwin on Windows 10 (64 bit):
$ gcc -std=c11 -pthread -o test-concurrent-read test-concurrent-read.c
$ ./test-concurrent-read
Starting thread...
Starting main loop...
.............................................................................................
Received: 'This is sample input which is consumed as if it was read from a (very slow) external device.'
$
I guess, it is worth to mention why there is no mutex guarding for pBuffer which is used in main() as well as in threadRead().
pBuffer is initialized in main() before pthread_create() is called.
While thread_read() is running, pBuffer is used by it exclusively (via its passed address in pPBuffer).
It is accessed in main() again but not before pthread_join() which grants that threadRead() has ended.
I tried to find a reference by google to confirm that this procedure is well-defined and reasonable. The best, I could find was SO: pthread_create(3) and memory synchronization guarantee in SMP architectures which cites The Open Group Base Specifications Issue 7 - 4.12 Memory Synchronization.

libusb - Segmentation fault: 11

I've got a very basic, bare minimum libusb example going, which compiles, but the output produced by the following application:
#include <stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
int main(void) {
puts("Looking for USB devices...");
libusb_device **devices;
libusb_context *context = NULL;
ssize_t device_count = 0;
device_count = libusb_get_device_list(context, &devices);
if(device_count < 0) {
puts("Unable to retrieve USB device list!");
}
printf("%lu devices found\n", device_count);
return EXIT_SUCCESS;
}
is as follows:
Looking for USB devices...
Segmentation fault: 11
The failure occurs on line 13:
device_count = libusb_get_device_list(context, &devices);
I'm running the above on Mac OS X 10.9, and have libusb version 1.0.9 installed via Homebrew.
Any idea what could be the problem?
The code misses to initialise context.
Call libusb_init() prior to any operation on libusb.
Add a line like this before issueing any other call into libusb:
int result = libusb_init(&context);
if (0 > result)
{
fprintf(stderr, "libusb_init() failed with %d.\n", result);
exit(EXIT_FAILURE);
}

Bus error in C Program on Unix machine

I'm fairly unexperienced with C and am running into a "Bus error" that I cannot understand the cause of. I had never heard of gdb but came across it on this forum and tried using it on my problem program and got the following output:
% gdb Proc1 GNU gdb 5.0
...
This GDB was
configured as
"sparc-sun-solaris2.8"...
(no
debugging symbols found)...
(gdb) run
Starting program:
/home/0/vlcek/CSE660/Lab3/Proc1
(no
debugging symbols found)...
(no
debugging symbols found)...
(no
debugging symbols found)...
Program
received signal SIGSEGV, Segmentation
fault. 0x10a64 in main ()
I have no idea what this means, is that saying there's an error in line 10 in my code? If so, line 10 in my code is merely "int main()" so I'm not sure the issue there... When I try running the program all it says is "Bus error" so I'm not sure where to go from here. I even tried putting a printf right after main and it doesn't print the string, only gives me a Bus error.
Below is my code:
// Compilation Command: gcc -o Proc1 Proc1.c ssem.o sshm.o
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "ssem.h"
#include "sshm.h"
// Code of Proc1
int main()
{int i, internal_reg;
int key1 = 111111, key2 = 222222, key3 = 333333, key4 = 444444;
/* here create and initialize all semaphores */
int sem1 = sem_create(key1, 1);
if (sem1 < 0) {
perror("sem failed");
}
int sem2 = sem_create(key2, 1);
if (sem2 < 0) {
perror("sem failed");
}
int sem3 = sem_create(key3, 1);
if (sem3 < 0) {
perror("sem failed");
}
int sem4 = sem_create(key4, 1);
if (sem4 < 0) {
perror("sem failed");
}
/* here created: shared memory array Account of size 3 */
int *Account;
int shmid = shm_get(123456, (void**) &Account, 3*sizeof(int));
if (shmid < 0) {
perror("shm failed");
}
Account[0]=10000;
Account[1]=10000;
Account[2]=10000;
/* synchronize with Proc2, Proc3 and Proc4 (4 process 4 way synchronization)*/
for (i = 0; i < 1000; i++)
{
sem_signal(sem1);
sem_signal(sem1);
sem_signal(sem1);
internal_reg = Account[0];
internal_reg = internal_reg - 200;
Account[0] = internal_reg;
/* same thing, except we're adding $100 to Account1 now... */
internal_reg = Account[1];
internal_reg = internal_reg + 200;
Account[1] = internal_reg;
if (i % 100 == 0 && i != 0) {
printf("Account 0: $%i\n", Account[0]);
printf("Account 1: $%i\n", Account[1]);
}
if (i == 300 || i == 600) {
sleep(1);
}
sem_wait(sem2);
sem_wait(sem3);
sem_wait(sem4);
}
/* Here add a code that prints contents of each account
and their sum after 100th, 200th, 300th, ...., and 1000th iterations*/
}
/*in the code above include some wait and signal operations on semaphores. Do no
t over-synchronize. */
Here is the documentation for ssem and sshm:
/*
* ssem.c
*
* Version 1.0.0
* Date : 10 Jan 2002
*
*/
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include "ssem.h"
#define PERMS 0600
static struct sembuf op_lock[1] = {
0, -1, 0
};
static struct sembuf op_unlock[1] = {
0, 1, IPC_NOWAIT
};
int sem_create(int key,int initval)
{
int semid,i;
semid = semget((key_t)key, 1, IPC_CREAT | PERMS);
for(i=0;i<initval;i++)
semop(semid,&op_unlock[0],1);
return semid;
}
int sem_open(int key)
{
int semid;
semid = semget(key,0,0);
return semid;
}
int sem_wait(int semid)
{
return semop(semid,&op_lock[0],1);
}
int sem_signal(int semid)
{
return semop(semid,&op_unlock[0],1);
}
int sem_rm(int semid)
{
return semctl(semid, 0, IPC_RMID, 0);
}
/*
* sshm.c
*
* Routines for Simpler shared memory operations
* Version : 1.0.0.
* Date : 10 Jan 2002
*
*/
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include "sshm.h"
#define PERMS 0600
int shm_get(int key, void **start_ptr, int size)
{
int shmid;
shmid = shmget((key_t) key, size, PERMS | IPC_CREAT);
(*start_ptr) = (void *) shmat(shmid, (char *) 0, 0);
return shmid;
}
int shm_rm(int shmid)
{
return shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
}
After compiling Proc1.c with the -ggdb flag and running gdb I got the following:
Program received signal SIGSEGV,
Segmentation fault. 0x10a64 in main ()
at Proc1.c:36
36 Account[0]=10000
Why would this cause a segmentation fault?
After changing the declaration of Account to
int *Account = 0;
and adding
printf("Account == %p\n", Account);
before Account[0] = 10000;
I get the following upon running Proc1:
Account == ffffffff
Bus error
In order to get more sensible results from gdb you should compile your program with the -ggdb option. This will then include debugging information (like line numbers) into your program.
What you are currently seeing is the memory address (0x10a64) of the program counter. This will not help you very much unless you can correlate the assembly instructions you find there with a part of your C program yourself.
It looks like you are using shm_get properly. I think the library designer has made a terrible mistake in naming the function so similarly to shmget.
It's just as I thought. The Account pointer is ending up with an invalid value (aka 0xffffffff (aka (void *)(-1))) in it. The value (void *)(-1) generally indicates some sort of error, and it is explicitly mentioned in the manpage for shmat. This indicates that the shmat call inside the library failed. Here is how you can tell if it failed:
if (Account == (void *)(-1)) {
perror("shmat failed");
}
Account[0] = 10000;
// ...
Now, why it failed is an interesting mystery. Apparently the shmget call succeeded.
Personally, I think System V IPC is basically deprecated at this point and you should avoid using it if you can.
Depending on your compiler and your compiler options you might encounter an aliasing problem because your are casting the address of your Account pointer. These oldish interfaces are not in phase with modern antialiasing rules, meaning that the optimizer supposes that the value of Account wouldn't change.
Also you should get the argument for shm_get as close as possible to the expected type. Try perhaps something like the following.
void volatile* shmRet;
int shmid = shm_get(123456, (void**) &shmRet, 3*sizeof(int));
int *Account = shmRet;
I don't have the same architecture, so I don't know the exact prototype of your shm_get but usually it is also a bad idea to use fixed keys for this type of functions. There should be some function that returns you some key to use in your application.

segmentation fault once sending message with gnokii gn_sms_send

here are the code folks :
#include <stdio.h>
#include <stdlib.h>
#include <gnokii.h>
#include <signal.h>
/*
*
*/
#define _(x) x
struct gn_statemachine *state = NULL;
void busterminate(void) {
gn_lib_phone_close(state);
gn_lib_phoneprofile_free(&state);
gn_lib_library_free();
}
void businit(void) {
gn_error error;
atexit(busterminate);
error = gn_lib_phoneprofile_load(NULL, &state);
if (GN_ERR_NONE == error) {
error = gn_lib_phone_open(state);
}
if (GN_ERR_NONE != error) {
fprintf(stderr, "%s\n", gn_error_print(error));
exit(-1);
}
}
void signal_handler(int signal) {
(void)signal;
exit(-2);
}
int main(int argc, char *argv[]) {
gn_data *data;
gn_sms sms;
gn_error error;
businit();
signal(SIGINT, signal_handler);
gn_data_clear(data);
sprintf(sms.remote.number,"%s","+628571641111");
sprintf(sms.user_data[0].u.text,"%s","tesss");
data->message_center = calloc(1, sizeof(gn_sms_message_center));
data->message_center->id= 1;
error = gn_sm_functions(GN_OP_GetSMSCenter, data, state);
if(error == GN_ERR_NONE)
{
snprintf(sms.smsc.number,sizeof(sms.smsc.number),"%s",data->sms->smsc.number); // set to sms.smsc.number from data.sms.smsc.number
sms.smsc.type = data->message_center->smsc.type;
//g_slice_free(gn_sms_message_center,data->message_center); // free the ram
free(data->message_center);
}
if(!sms.smsc.number[0])
{
printf("failed once getting sms center number\n");
}
if(!sms.smsc.type)
{
sms.smsc.type = GN_GSM_NUMBER_Unknown;
}
data->sms = &sms;
//send the message
error = gn_sms_send(data,state);
if(error == GN_ERR_NONE)
{
if(sms.parts > 1)
{
int j;
printf("sms sent with : %d parts, and reference number is : ", sms.parts);
for(j=0; j < sms.parts; j++)
{
printf("%d\n",sms.reference[j]);
}
}
else
{
printf("one sms sent with reference number : %d\n",sms.reference[0]);
}
}
else
{
printf("libgnokii error : %s\n",gn_error_print(error));
}
free(sms.reference);
return 0;
}
im gonna send an sms to +628571641111, with the text "tesss", but unfortunately the OS said it segmentation fault, thus, where is my fault ?
$ gnokii --identify
GNOKII Version 0.6.29
IMEI : 3556XXXXX509XXX
Manufacturer : ZTE INCORPORATED
Model : MF627
Product name : MF627
Revision : BD_3GHAP673A4V1.0.0
$ gdb -q ./gnokii_send_sms
Reading symbols from /root/gnokii_send_sms...(no debugging symbols found)...done.
(gdb) r
Starting program: /root/gnokii_send_sms
[Thread debugging using libthread_db enabled]
Program received signal SIGSEGV, Segmentation fault.
0x00317334 in ?? () from /lib/libc.so.6
(gdb)
You're passing to gn_data_clear a pointer you haven't initialized yet. In the beginning of your main function you need to have
gn_data data;
Not
gn_data *data;
Here's the function implementation:
GNOKII_API void gn_data_clear(gn_data *data)
{
memset(data, 0, sizeof(gn_data));
}

Resources