1
votes

First my environment: GCC 4.9.2, Debian Linux 3.16 x86_64. I working on someone else's code so I'm changing things as I go (I hope I'm fixing things ...). I've run into a SIGSEGV, but it seems that gdb loses it's mind with a trace that doesn't point back to a stack in my program (hmm). So I've resorted to printf's. To make a long story short (too late), I think I've traced it back to this:

In my main() routine I have this code:

char buffer[256] = { [0 ... 255] = 0x00 }; // Neat, not seen this before

This buffer gets used in various places and the code limits the reads with a typical read of 100 or less bytes. But I've noticed that when the code runs that the address of the buffer changes (in the main() still):

i = 0x82; // char i;
fprintf(stderr, "C &buffer = %p\n", buffer);
BP_WriteToPirate(fd, &i);
fprintf(stderr, "D &buffer = %p\n", buffer);

After compiling with:

gcc -g3 -Wall -Os -DTRUE=1 -DFALSE=0 -DVERSION=\"V0.15\"   -c -o main.o main.c
gcc -g3 -o spisniffer serial.o buspirate.o main.o cleanup.o 

And running I see this bit of output:

    C &buffer = 0x7fffffffe290
    W> 0x82 size = 1 (1)
    D &buffer = 0x7fffffffe200

The code in between is:

uint32_t BP_WriteToPirate(int fd, char *val) {
    int res = -1;
    char ret = 0;

    write(fd, val, 1);

    if (disable_comport != 1) {  //if comport is enable, we need a response from the port
        res = serial_read(fd, &ret, 1);

        if( ret != 0x01) {
            if (modem==TRUE){
                printf("Modem responded with %i byte and with a value of 0X%X\n",res,ret);
            } else {
                printf("ERROR\n");
                return -1;
            }
        }
    }

    return 0;
}

If I replace the char buffer[256] declaration with a char *buffer = malloc(sizeof(char)*256), the problem seems to not occur again.

So am I looking at a stupid mistake or do I have a bug in system calls/libraries? Any pointers on debugging tips?

3
You may be corrupting the stack. Please show a minimal, complete example. If you take out specific function calls, and the problem goes away, then remove the code, then add back parts until the problem appears to narrow down the location of the error. - OldProgrammer
Caution: char buffer[256] = { [0 ... 255] = 0x00 }; is a range initializer, and is not yet part of the C standard. It is an extension on some compilers, but makes your code non-portable. - ryyker
char buffer[256] = { [0 ... 255] = 0x00 }; is an extension, char buffer[256] = { 0 }; does exactly the same thing. - chqrlie
Welcome to Stack Overflow. Please read the About page before too long. More immediately, you need to read about how to create an MCVE (How to create a Minimal, Complete, and Verifiable Example?). What you're seeing shouldn't happen — it isn't clear what could be going wrong. But without a reproducible and minimal (single file, minimal functions — probably 2 here, main() and a variant of your BP_WriteToPirate() function) sample, we can't readily predict what you're doing wrong. - Jonathan Leffler
I'm working on getting something to post but the first go-around has removed the error (I removed the getopts section of code and some printfs). So that was useful. :-) I'll also remove the non-portable code also (when in doubt, do without). Thanks - Neil Cherry

3 Answers

1
votes

Use the tool Valgrind to look for invalid read/write in your program

0
votes

The following files all compile cleanly.

Im on ubuntu linux 14.04 using gcc -Wall -Wextra -pedantic -Wconversion -std=c99 -c to compile each file

Notice there were many small changes to the code to obtain the clean compiles.

You can perform a 'diff' 'cmp' or similar function to highlight the changes made to get the clean compiles.

Some of the changes involved:

  1. corrected the usage statements in the printusage() function
  2. corrected the list of #include statements
  3. corrected declaration of i as unsigned char rather than char
  4. corrected declaration of certain other variables from int to either ssize_t or size_t, as needed
  5. removed the two different typedef's for speed_t so the code uses the typedef in the thermos.h header file
  6. changed return type on a function from uint32_t to int32_t so function could return a proper -1 value when errors occur
  7. corrected the indenting of the code for consistency/readability
  8. for function: BP_WriteToPirate() carried forward the correct second parameter type from int* to unsigned int*
  9. properly cast parameters to t_opt.c_... flags to unsigned int rather than the default int, but only for the not defined NJC
  10. modified the contents of certain error messages to include the strerror(errno) string
  11. corrected exit from serial_read() to always NUL terminate the input buffer
  12. added #defines for FALSE and TRUE
  13. when inputting speed from the parameter list, used atol() rather than atoi() so data type would match the typedef speed_t
  14. one still existing problem is the actual value pasted to the cfsetispeed(&t_opt, speed); and cfsetospeed(&t_opt, speed);` functions must be from the set defined in thermos.h not the actual baud rate, because the parameter must be one of the valid bitmap'd values not some long int.

Caveat: my system has no modem nor 'bus pirate` so could not perform extensive testing however: with no (or bad) parameters: the following was output:

-------------------------------------------------------

 Bus Pirate binary mode SPI SNIFFER utility v0.2 (CC-0)
 http://dangerousprototypes.com

-------------------------------------------------------


&buffer = 0x7ffed4128010
ERROR: Invalid argument(s).

Help Menu


-------------------------------------------------------

 Usage:              
   ./untitled  -d device -e 1 -p 0 

   Example Usage:   ./untitled -d /dev/ttyUSB0 -s 115200 -e 1 -p 0 

           Where: -d device is port e.g.  /dev/ttyUSB0
                  -s Speed is port Speed  default is 115200 
                  -e ClockEdge is 0 or 1  default is 1 
                  -p Polarity  is 0 or 1  default is 0 
                  -r RawData is 0 or 1    default is 0 


-------------------------------------------------------

with reasonably good parameters, the following was output:

./untitled -d /dev/ttyUSB0 -s 115200 -e 1 -p 0 -r 0 
-------------------------------------------------------

 Bus Pirate binary mode SPI SNIFFER utility v0.2 (CC-0)
 http://dangerousprototypes.com

-------------------------------------------------------


&buffer = 0x7ffd5a4b35f0
A &buffer = 0x7ffd5a4b35f0
Parameters used: Device = /dev/ttyUSB0,  Speed = 115200, Clock Edge= 1, Polarity= 0
 Opening Bus Pirate on /dev/ttyUSB0 at 115200bps...
Could not open serial port due to: No such file or directory.Error opening serial port

When I modified the code to ignore the failure to open the serial port then this resulted: with the same counting sequence repeated forever.

0 Sync (0x00/0)
0 Sync (0x00/1)
0 Sync (0x00/2)
...
0 Sync (0x00/120)
0 Sync (0x00/121)
0 Sync (0x00/122)
0 Sync (0x00/0)

and there was no shift in the stack pointer so the buffer[] array did not move

main.c

/*
 * This file is part of the Bus Pirate project (http://code.google.com/p/the-bus-pirate/).
 *
 * Written and maintained by the Bus Pirate project and http://dangerousprototypes.com
 *
 * To the extent possible under law, the project has
 * waived all copyright and related or neighboring rights to Bus Pirate. This
 * work is published from United States.
 *
 * For details see: http://creativecommons.org/publicdomain/zero/1.0/.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

// added
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // getopt(), usleep()
#include <string.h> // strdup()
#include <errno.h>

#include <stdint.h>
#include <signal.h>

#define FALSE (0)
#define TRUE (~FALSE)

#ifdef WIN32
    #include <conio.h>
    #include <windef.h>
#else
    //#include <curses.h>
#endif

#include "buspirate.h"
#include "serial.h"

int modem;   //set this to TRUE of testing a MODEM
int verbose;
int disable_comport = 0;   //1 to say yes, disable comport, any value to enable port default is 0 meaning port is enable.
int dumphandle;     // use by dump file when using the -d dumfile.txt parameter
char *dumpfile;

#define SPI 0x01

int print_usage(char * appname)
{
    //print usage
    printf("\n\n");

    // added '-d com1 in two places
    printf("-------------------------------------------------------\n");
    printf("\n");
    printf(" Usage:              \n");
    printf("   %s  -d device -e [0|1] -p [0|1] -d deviceName\n ",appname);
    printf("\n");
    printf("   Example Usage:   %s -d /dev/ttyUSB0 -s 115200 -e 1 -p 0 \n",appname);
    printf("\n");
    printf("           Where: -d device is port e.g.  /dev/ttyUSB0\n");
    printf("                  -s Speed is port Speed  default is 115200 \n");
    printf("                  -e ClockEdge is 0 or 1  default is 1 \n");
    printf("                  -p Polarity  is 0 or 1  default is 0 \n");
    printf("                  -r RawData is 0 or 1    default is 0 \n");
    printf("\n");

    printf("\n");

    printf("-------------------------------------------------------\n");

    return 0;
}


int main(int argc, char** argv)
{
    int opt;
    int fd;
    int res;
    int c;
    int new_state;
    int state = 0;

    //char buffer[256] = { [0 ... 255] = 0x00 };
    char buffer[256] = {  0x00 };
    //char *buffer = malloc(sizeof(char) * 256);
    unsigned char i; // was char i;

    char *param_port      = NULL;
    char *param_polarity  = NULL;
    char *param_clockedge = NULL;
    char *param_rawdata   = NULL;
    char *param_speed     = NULL;
    int   speed;

    printf("-------------------------------------------------------\n");
    printf("\n");
    printf(" Bus Pirate binary mode SPI SNIFFER utility v0.2 (CC-0)\n");
    printf(" http://dangerousprototypes.com\n");
    printf("\n");
    printf("-------------------------------------------------------\n");
    printf("\n\n");

    fprintf(stderr, "&buffer = %p\n", buffer);

    if (argc <= 1)
    {
        printf("ERROR: Invalid argument(s).\n\n");
        printf("Help Menu\n");
        print_usage(argv[0]);
        exit(-1);
    }

    while ((opt = getopt(argc, argv, "ms:p:e:d:r:")) != -1)
    {
        // printf("%c  \n",opt);
        switch (opt)
        {
            case 'd':  // device   eg. com1 com12 etc
                if ( param_port != NULL)
                {
                    printf("Device/PORT error!\n");
                    exit(-1);
                }
                param_port = strdup(optarg);
                break;

            case 'e':      // clock edge
                if (param_clockedge != NULL)
                {
                    printf("Clock Edge should be 0 or 1\n");
                    exit(-1);
                }
                param_clockedge = strdup(optarg);
                break;

            case 'p':
                if (param_polarity != NULL)
                {
                    printf("Polarity must be 0 or 1\n");
                    exit(-1);
                }
                param_polarity = strdup(optarg);
                break;

            case 's':
                if (param_speed != NULL)
                {
                    printf("Speed should be set: eg  115200 \n");
                    exit(-1);
                }
                param_speed = strdup(optarg);
                speed       = atoi(param_speed);
                break;

            case 'r':      // raw data
                if (param_rawdata != NULL)
                {
                    printf("Raw Data should be 0 or 1\n");
                    exit(-1);
                }
                param_rawdata = strdup(optarg);
                break;

            case 'm':       // modem debugging for testing
                modem =TRUE;    // enable modem mode
                break;

            default:
                printf("Invalid argument %c", opt);
                print_usage(argv[0]);
                //exit(-1);
                break;
        }
    } // end while


    fprintf(stderr, "A &buffer = %p\n", buffer);

    if (param_port==NULL)
    {
        printf("No serial port set\n");
        print_usage(argv[0]);
        exit(-1);
    }

    if (param_clockedge==NULL)
    {
        param_clockedge=strdup("1");
    }

    if (param_polarity==NULL)
    {
        param_polarity=strdup("0");
    }

    if (param_speed==NULL)
    {
        param_speed = strdup("115200");
        speed = 115200;
    }

    if (param_rawdata==NULL)
    {
        param_rawdata=strdup("0");
    }

    printf("Parameters used: Device = %s,  Speed = %s, Clock Edge= %s, Polarity= %s\n",param_port,param_speed,param_clockedge,param_polarity);

    //
    // Open serial port
    //
    printf(" Opening Bus Pirate on %s at %dbps...\n", param_port, speed);
    fd = serial_open(param_port);
    if (fd < 0)
    {
        fprintf(stderr, "Error opening serial port\n");            //serial_write( fd, "\x0E", 1);
        //serial_write( fd, &'0x0E', 1);
        return -1;
    }

    //
    // Enter binary mode, then enter a protocol mode
    //
    serial_setup(fd, (speed_t) speed);

    //printf(" Starting SPI sniffer...\n");
    if (modem == TRUE)
    {    // connected to modem for testing response

        serial_write( fd, "ATI3\x0D\0",5 );
        usleep(1);
        res= serial_read(fd, buffer, sizeof(buffer));
        printf("\n %s\n",buffer);

        serial_write( fd, "ATI4\x0D\0",5 );
        usleep(1);
        res= serial_read(fd, buffer, sizeof(buffer));
        printf("\n %s\n",buffer);

        serial_write( fd, "ATI7\x0D\0",5 );
        usleep(1);
        res= serial_read(fd, buffer, sizeof(buffer));
        printf("\n %s\n",buffer);
    }

    else
    {
        fprintf(stderr, " Configuring Bus Pirate...\n");
        fprintf(stderr, "B &buffer = %p\n\n", buffer);
        BP_EnableMode(fd, SPI); //enter BBIO then SPI
        //
        //Start sniffer
        //

        //configure according to user settings
        //1000wxyz - SPI config, w=HiZ/3.3v, x=CKP idle, y=CKE edge, z=SMP sample
        i = 0x80;

        if(strncmp(param_clockedge, "1", 1)==0)
        {
            i |= 0x02;
        }

        if(strncmp(param_polarity, "1", 1)==0)
        {
            i |= 0x04;
        }

        fprintf(stderr, "C &buffer = %p\n", buffer);
        BP_WriteToPirate(fd, &i);
        fprintf(stderr, "D &buffer = %p\n", buffer);

        // start the sniffer
        fprintf(stderr, "start the sniffer\n");

        // Yes this is goofy but it kept trying to writ 0xffffff82 instead of 0x0E
        char t[] = { 0x0E, 0x00 };

        serial_write( fd, t, 1);

        //
        // Done with setup
        //
        fprintf(stderr, "E &buffer = %p\n", buffer);

    }

    printf("Happy sniffing! Ctrl-C (^C) to stop.\n");

    // 000011XX - Sniff SPI traffic when CS low(10 ^N)/all(01 ^M)
    // 0x60 = `  30khz
    // 0x61 = a 125khz
    // 0x67 = b 250khz
    // 0x67 = c 1.0 Mhz
    // 0x67 = d 2.0 Mhz
    // 0x67 = e 2.6 Mhz
    // 0x67 = f 4.0 Mhz
    // 0x67 = g 8.0 Mhz
    //
    // Loop and print input from the serial port
    /*
    ** ###
    ** ### @FIXME: Major issue with a SIGSEGV but I can't figure it out!
    ** ###
    ** ### If I attempt to use char buffer[256] it moves from one address to
    ** ### another in the code above (is that normal?). So I'm guessing
    ** ### something in the BP_WriteToPirate() (above) is wrong as this is where
    ** ### the change occurs. I've malloc'd a buffer of 256 bytes and the code
    ** ### seems happier (ie, no SIGSEGV but no solution either).
    ** ###
    */
    fprintf(stderr, "X FD = %d &buffer = %p\n" , fd, buffer);

    while(1)
    {
        usleep(1);
        //res = serial_read(fd, ptr, 100);
        res = serial_read(fd, buffer, 100);

        if(res == -1)
        {
            // For some reason we get an error
            // So close the port and reopen it
            fprintf(stderr, "(%d) Read errno: %s\n", fd, strerror(errno));
            if(errno == EBADF)
            { // 9
                close(fd);

                fd = serial_open(param_port);
                if (fd < 0)
                {
                    fprintf(stderr, "Error opening serial port\n");
                    return -1;
                }

                //
                // Enter binary mode, then enter a protocol mode
                //
                serial_setup(fd, (speed_t) speed);
            }
        }

        else if(res > 0)
        {
            for(c = 0; c < res; c++)
            {
                if(strncmp(param_rawdata, "1", 1)==0)
                {
                    printf("%02X ", (uint8_t) buffer[c]);
                }

                else
                {
                    switch(state)
                    {
                        default:
                        // fall through
                        case 0: // waiting CS active
                            if (buffer[c] == 0x5B)
                            {
                                printf("[");
                                new_state = 1;
                            }

                            else
                            {
                                printf("0 Sync (0x%02x/%d)\n", buffer[c], c);
                                new_state = 0;
                            }
                            break;

                        case 1: // check for data or CS inactive
                            if (buffer[c] == 0x5C)
                            {
                                new_state = 2;
                            }

                            else if (buffer[c] == 0x5D)
                            {
                                printf("]\n");
                                new_state = 0;
                            }

                            else
                            {
                                printf("1 Sync (0x%02x)\n", buffer[c]);
                                new_state = 0;
                            }
                            break;

                        case 2: // MPI
                            printf("0x%02X(", (uint8_t) buffer[c]);
                            new_state = 3;
                            break;

                        case 3: // MPO
                            printf("0x%02X)", (uint8_t) buffer[c]);
                            new_state = 1;
                            break;
                    } // end switch
                    state = new_state;
                } // end if
            } // end for
        } // end if
    }    // ^C to stop



    free(param_port);
    free(param_speed);
    return 0;
}

serial.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

#include <string.h>

#include "serial.h"

extern int disable_comport;
extern char *dumpfile;

int serial_setup(int fd, speed_t speed)
{
    struct termios t_opt;

#ifdef NJC
    int s = tcgetattr(cm11, &oldsb);

    if (s < 0)
    {
        perror("ttopen tcgetattr");
        exit(1);
    }

    newsb = oldsb;
#ifndef BUSPIRATE_h_
#define BUSPIRATE_h_

#include <stdint.h>


int32_t BP_WriteToPirate(int fd, unsigned char * val);
void BP_EnableMode(int fd, char bbmode);

#endif

    newsb.c_iflag = IGNBRK | IGNPAR;
    newsb.c_oflag = 0;
    newsb.c_lflag = ISIG;
    newsb.c_cflag = (CLOCAL | B4800 | CS8 | CREAD);

    for (s = 0; s < NCC; s++)
    {
        newsb.c_cc[s] = 0;
    }

    newsb.c_cc[VMIN]   = 1;
    newsb.c_cc[VTIME]  = 0;

    tcsetattr(cm11, TCSADRAIN, &newsb);
#else
    /* set the serial port parameters */
    fcntl(fd, F_SETFL, 0);
    tcgetattr(fd, &t_opt);

    cfsetispeed(&t_opt, speed);
    cfsetospeed(&t_opt, speed);

    t_opt.c_cflag |= (unsigned)(CLOCAL | CREAD);
    t_opt.c_cflag &= (unsigned)~PARENB;
    t_opt.c_cflag &= (unsigned)~CSTOPB;
    t_opt.c_cflag &= (unsigned)~CSIZE;
    t_opt.c_cflag |= (unsigned)CS8;
    t_opt.c_lflag &= (unsigned)~(ICANON | ECHO | ECHOE | ISIG);
    t_opt.c_iflag &= (unsigned)~(IXON | IXOFF | IXANY);
    t_opt.c_oflag &= (unsigned)~OPOST;
    t_opt.c_cc[VMIN] = 0;
    //t_opt.c_cc[VTIME] = 10;
    t_opt.c_cc[VTIME] = 1;

    tcflush(fd, TCIFLUSH);

    tcsetattr(fd, TCSANOW, &t_opt);
#endif
    return 0;
} // end function: serial_setup


int serial_write(int fd, char *buf, int size)
{
    ssize_t ret = 0;

    ret = write(fd, buf, (size_t)size);

    fprintf(stderr, "W> ");

    for(int i = 0; i < size; i++)
    {
        fprintf(stderr, "0x%02x ", (unsigned char) buf[i]);
    }

    fprintf(stderr, "size = %d (%ld)\n", size, ret);

    return (int)ret;
} // end function; serial_write


int serial_read(int fd, char *buf, int size)
{
    ssize_t len = 0;
    ssize_t ret = 0;
    int     timeout = 0;

    while ( len < size)
    {
        //fprintf(stderr, "FD = %d &buffer = %p (%d)\n" , fd, buf, sizeof(buf));
        ret = read(fd, buf+len, (size_t)(size-len));
        if (ret == -1)
        {
            buf[len] = '\0';
            return -1;
        }

        if (ret == 0)
        {
            timeout++;

            if (timeout >= 10)
            {
                break;      // Break out and return from this function
            }

            else
            {
                continue;   // Just continue the loop
            }
        }

        len += ret;
    } // end while

    //if( len > 255)
    //{
    //    buf[255] = 0x00;    // Buffer's length is 256
    //}

    //else
    //{
        buf[len] = 0x00;
    //}
    return (int)len;
} // end function: serial_read


int serial_open(char *port)
{
    int fd;
    fd = open(port, O_RDWR | O_NOCTTY);

    if (fd == -1)
    {
        fprintf(stderr, "Could not open serial port due to: %s.", strerror( errno ) );
        return -1;
    }

    return fd;
} // end function: serial_open


int serial_close(int fd)
{
    close(fd);

    return 0;
} // end function: serial_close

buspirate.c

#define _GNU_SOURCE

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "serial.h"
#include "buspirate.h"

//static struct BP_t pBP;
//static uint8_t BP_reversebyte(uint8_t c);
//static char bpbuf[4096];
//static int bpbufcnt;

extern int disable_comport;
extern int dumphandle;
extern int verbose;
extern int modem;

// added
#define FALSE (0)
#define TRUE (~FALSE)


// low lever send command, get reply function
int32_t BP_WriteToPirate(int fd, char *val)
{
    int res = -1;
    char ret = 0;

    serial_write(fd, val, 1);

    if (disable_comport != 1)
    {  //if comport is enable, we need a response from the port
        res = serial_read(fd, &ret, 1);

        if( ret != 0x01)
        {
            if (modem==TRUE)
            {
            printf("Modem responded with %i byte and with a value of 0X%X\n",res,ret);
            }

            else
            {
                printf("ERROR\n");
                return -1;
            }
        }
    }

    return 0;
} // end function: BP_WriteToPirate


/*
** Put the Buspirate into raw binary mode by sending 20 nulls
** expect BBIO1
** Then put it into SPI raw mode by sending it 0x01
** expect SPI1
*/
void BP_EnableMode(int fd, char bbmode)
{
    int ret;
    char tmp[100] = { 0x00 };
    int done = 0;
    //int cmd_sent = 0;
    int tries = 0;

    printf(" Entering binary mode...\n");
    if (fd == (-1))
    {   //added because the fd has already returned null
        printf("Port does not exist!");
        return;
    }

    // -[ BBIO1 - Binary mode ]-------------------------------------------------
    while (!done)
    {
        tmp[0] = 0x00;

        serial_write(fd, tmp, 1);
        tries++;
        usleep(1);

        ret = serial_read(fd, tmp, 5);

        if (modem==TRUE)
        {
            // ???
            printf("\nModem Responded = %i\n", ret);
            done=1;
        }

        else
        {
            if (ret != 5 && tries > 20)
            {
                fprintf(stderr, "Buspirate did not respond correctly :( %i \n", ret );
                exit(-1);
            }

            else if (strncmp(tmp, "BBIO1", 5) == 0)
            {
                printf("read returned %i:%s\n", ret, tmp);
                done=1;
            }
        }

        if (tries > 25)
        {
            printf("Buspirate:Too many tries in serial read! -exiting \n - chip not detected, or not readable/writable\n");
            exit(-1);
        }
    } // end while

    // -----------------------------------------------------------------------
    printf("BP found\n");

    // -[ SPI mode ]------------------------------------------------------------
    // 00000001 - Enter raw SPI mode, display version string
    //
    // Once in raw bitbang mode, send 0x01 to enter raw SPI mode. The
    // Bus Pirate responds 'SPIx', where x is the raw SPI protocol
    // version (currently 1). Get the version string at any time by
    // sending 0x01 again.
    done = 0;
    tmp[0] = bbmode;
    tmp[1] = 0x01;
    //printf("Sending 0X%02X to port\n",tmp[0]);
    serial_write(fd, tmp, 1);
    //tries++;
    usleep(1);

    ret = serial_read(fd, tmp, 5);

    if (modem == TRUE)
    {
            printf("Modem Responded = %i with value %#X\n",ret,tmp[0]);
    }

    else
    {
        if ( (ret >= 4) && (strncmp(tmp, "SPI1", 4) == 0))
        {
            printf("In SPI mode (%d/%s)\n", ret, tmp);
        }

        else
        {
            fprintf(stderr, "Buspirate did not respond correctly :( %i [ ", ret );
            // reusing tries instead of creating a new var, yeah, just lazy ;-)
            for(tries = 0; tries < ret; tries++)
            {
                fprintf(stderr, "0x%02x ", tmp[tries]);
            }
            fprintf(stderr, "] %s\n", tmp);

            printf("Sending 0X%02X to port\n", 0x01);
            tmp[0] = 0x01;
            tmp[1] = 0x01;
            serial_write(fd, tmp, 1);
            usleep(1);

            if ( (ret==4) && (strncmp(tmp, "SPI1", 4) == 0))
            {
                fprintf(stderr, "Yea: %s [ ", tmp ); //
            }

            else
            {
                ret = serial_read(fd, tmp, 5);

                printf("Sending 0X%02X to port\n", 0x01);
                tmp[0] = 0x01;
                tmp[1] = 0x01;
                serial_write(fd, tmp, 2);
                usleep(1);

                ret = serial_read(fd, tmp, 5);

                if ( (ret==4) && (strncmp(tmp, "SPI1", 4) == 0))
                {
                    fprintf(stderr, "Yea: %s [ ", tmp ); //
                }

                else
                {
                    if((ret==5) && (strncmp(tmp, "SPI1", 5) == 0))
                    {
                        fprintf(stderr, "Yea: %s [ ", tmp ); //
                    }

                    else
                    {
                        fprintf(stderr, "Buspirate did not respond correctly :( %i [ ", ret );

                        // reusing tries instead of creating a new var, yeah, just lazy ;-)
                        for(tries = 0; tries < ret; tries++)
                        {
                            fprintf(stderr, "0x%02x ", tmp[tries]);
                        }

                        fprintf(stderr, "] %s\n", tmp);

                        exit(-1);
                    }
                }
            } // End if SPI1 else
        }
    }
} // end function: BP_EnableMode

serial.h

#ifndef MYSERIAL_H_
#define MYSERIAL_H_
/*
#ifdef WIN32
    #include <windows.h>
    #include <time.h>
    #define O_NOCTTY 0
    #define O_NDELAY 0
    #define B115200 115200
    #define B921600 921600
    #define OS WINDOWS
    int write(int fd, const void* buf, int len);
    int read(int fd, void* buf, int len);
    int close(int fd);
    int open(const char* path, unsigned long flags);
    int __stdcall select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfs, const struct timeval* timeout);
#else
    #include <unistd.h>
    #include <termios.h>
    #include <sys/select.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #ifdef MACOSX
        #include <IOKit/serial/ioss.h>
        #include <sys/ioctl.h>
        #define B1500000 1500000
        #define B1000000 1000000
        #define B921600  921600
    #endif
#endif
*/

#include <stdint.h>

#ifdef WIN32
#include <windows.h>
#include <time.h>

#define B115200 115200
#define B921600 921600

typedef long speed_t;
#else

#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>

#endif

int serial_setup(int fd, speed_t speed);
int serial_write(int fd, char *buf, int size);
int serial_read(int fd, char *buf, int size);
int serial_open(char *port);
int serial_close(int fd);


#endif

buspirate.h

#ifndef BUSPIRATE_h_
#define BUSPIRATE_h_

#include <stdint.h>


int32_t BP_WriteToPirate(int fd, unsigned char * val);
void BP_EnableMode(int fd, char bbmode);

#endif
0
votes

This may not be the reason for the surprising behavior you observe, but the pointer passed to fprintf for the %p specifier should be a void * or cast as such:

fprintf(stderr, "C &buffer = %p\n", (void*)buffer);

A more likely cause for your problem would be multiple definitions of buffer in different scopes in the main function. Provide the actual code that shows the problem, without a minimal compilable verifiable example, we can only make guesses.

EDIT: looking at the code you posted, It doesn t seem to be the latter. Very intriguing...