Arduino sketch compiled from Windows or Linux performs differently - linux

I have a very strange problem with a sketch which performs differently if compiled and uploaded to Arduino from Windows XP Home sp3 or Elementary OS Luna (a distro of Ubuntu Linux).
This sketch, between other things, reads a byte from a serial connection (bluetooth) and write it back to serial monitor.
This is what I get if I compile the sketch from WinXP: I sent over BT connection strings from "1" to "7" one time each. The ASCII code of these strings are reduced of 48 to transform string in byte. The result is correct, also functions in pointer array are correctly called.
and here is what I get from Linux. I sent 4 times each string from "1" to "7" to see that result has nothing to do with what I need to get and also is not consistent with the same input data: for example when I send string "2" I get 104 106 106 104..... and same byte 106 is written with different Strings coming from BT.
Also the functions are not called so it means that is not a Serial.print issue.
I'm sure it is a compiling issue because once the sketch is uploaded in Arduino it performs in the same way (correct or not) if I use serial monitor in WinXP or Linux.
Here's the sketch
#include "Arduino.h"
#include <SoftwareSerial.h>
#include <Streaming.h>
#define nrOfCommands 10
typedef void (* CmdFuncPtr) (); // this is a typedef to command functions
//the following declares an arry of 10 function pointers of type DigitFuncPtr
CmdFuncPtr setOfCmds[nrOfCommands] = {
noOp,
leftWindowDown,
leftWindowUp,
bootOpen,
cabinLightOn,
cabinLightOff,
lockOn,
lockOff,
canStart,
canStop
};
#define cmdLeftWindowDown 1
#define cmdLeftWindowUp 2
#define cmdBootOpen 3
#define cmdCabinLightOn 4
#define cmdCabinLightOff 5
#define cmdLockOn 6
#define cmdLockOff 7
#define cmdCanStart 8
#define cmdCanStop 9
#define buttonPin 4 // the number of the pushbutton pin
#define bluetoothTx 2
#define bluetoothRx 3
int buttonState = 0; // variable for reading the pushbutton status
int androidSwitch=0;
byte incomingByte; // incoming data
byte msg[12];
byte msgLen=0;
byte msgIdMsb=0;
byte msgIdLsb=0;
//const byte cmdLeftWindowDown;
SoftwareSerial bluetooth(bluetoothTx,bluetoothRx);
void setup()
{
//Setup usb serial connection to computer
Serial.begin(115200);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
//bluetooth.print("$$$");
randomSeed(analogRead(10));
delay(100);
//bluetooth.println("U,9600,E");
//bluetooth.begin(9600);
//time=0;
}
void loop() {
msgIdLsb=random(1,255);
msgIdMsb=random(0,5);
msg[0]=msgIdMsb;
msg[1]=msgIdLsb;
msgLen=random(9);
msg[2]=msgLen;
for (int x=3;x<msgLen+3;x++) {
msg[x]=random(255);
}
for (int x=3+msgLen;x<11;x++) {
msg[x]=0;
}
msg[11]='\n';
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
if ((buttonState == HIGH)||(androidSwitch==HIGH)) {
for (int x=0;x<12;x++) {
Serial<<msg[x]<<" ";
bluetooth.write(uint8_t(msg[x]));
}
Serial<<endl;
}
//Read from bluetooth and write to usb serial
if(bluetooth.available())
{
incomingByte = bluetooth.read()-48;
Serial<<incomingByte<<endl;
if (incomingByte<nrOfCommands)
setOfCmds[incomingByte]();
}
delay(10);
}
void noOp(void)
{
Serial<<"noOp"<<endl;
};
void leftWindowDown(void)
{
Serial<<"leftWindowDown"<<endl;
};
void leftWindowUp(void)
{
Serial<<"leftWindowUp"<<endl;
};
void bootOpen(void)
{
Serial<<"bootOpen"<<endl;
};
void cabinLightOn(void)
{
Serial<<"cabinLightOn"<<endl;
};
void cabinLightOff(void)
{
Serial<<"cabinLightOff"<<endl;
};
void lockOn(void)
{
Serial<<"lockOn"<<endl;
};
void lockOff(void)
{
Serial<<"lockOff"<<endl;
};
void canStart(void)
{
androidSwitch=HIGH;
};
void canStop(void)
{
androidSwitch=LOW;
};
Any help would be very helpful.
Thanks in advance.

I suppose you are using the arduino ide; if not, some of the following might not apply.
First, find out the location of the build directory the ide is using when it compiles and links the code. [One way to find out is to temporarily turn on Verbose output during compilation. (Click File, Preferences, "Show verbose output during compilation".) Click the Verify button to compile the code, and look at the path following the -o option in the first line of output.] For example, on a Linux system the build directory path might be something like /tmp/build3877126492387157498.tmp. In that directory, look for the .cpp file created during compilation.
After you find the .cpp files for your sketch on both systems, copy them onto one system so you can compare them and check for differences. If they are different, one or the other ide might be corrupt or an incorrect include might be occurring.
If the .cpp files differ, compare the compile flags, the header files, etc. I think the flags and AVR header files should be the same on both systems, with the possible exception that MSW files might have carriage return characters after the newline characters. Also check the gcc versions. [I don't have an MSW system to try, but I'm supposing that gcc is used on both systems for AVR cross-compiling. Please correct me if I'm wrong.]
If the .cpp files match, then test the generated binary files to find out where they differ. (For example, if the sketch file is Blink21x.ino, binary files might be Blink21x.cpp.elf or Blink21x.cpp.hex.) If you have a .elf file on both systems [I don't know if the MSW system will generate .elf] use avr-objdump on the Linux system to produce a disassembled version of code:
avr-objdump -d Blink21x.cpp.elf > Blink21x.cpp.lst
Then use diff to locate differences between the two disassembly files. Enough information is available in the .lst file to identify your source line if the difference is due to how your source was compiled, as opposed to a difference in libraries. (In the latter case, enough information is given in the .lst file to identify which library routines differ.)
If you don't have an .elf file on the MSW system, you might try comparing the .hex files. From the location of the difference you can find the relevant line in the Linux-system .elf-disassembly file, and from that can identify a line of your code or a library routine.

Related

Is there a way to make this crossplatform?

Im trying to get rid of a platform dependent code.
This code gets a string formated by a mask ("%Y-%m-%d %H:%M:%S") and convert it to std::tm struct and a std::time seconds.
I want to get rid of the need of preprocessor dependant blocks, as (imho) there must be a standard way of doing it in both platforms in the same way.
strptime does not exists in windows, std::get_time does not exists(?) on linux (g++ c++11).
Is there any way to make this code crossplatform (windows/linux) without using a factory pattern or preprocessor dependant blocks?
KDATETIME& KDATETIME::operator= (const char* k)
{
std::string smask;
smask = (std::string)this->mask;
std::string sk;
sk=k;
tm.tm_isdst=-1;
#ifdef WINDOWS <<---- THIS BLOCK
std::istringstream ss(sk);
ss >> std::get_time(&tm, smask.c_str());
#else
strptime(sk.c_str(), smask.c_str(), &tm);
#endif <<------
this->time = mktime(&tm); // t is now your desired time_t
[...]
}

is %llx or %llu not supposed to work with wsprintf?

I am using Visual Studio 2017 C++. When I use printf with a specification such as %llx or %llu everything works as expected. If I use the same format spec, %llu or %llx, with wsprintf, I get junk in the buffer instead of the result I had gotten with printf.
My question is: is there a way to get wsprintf to give the result that should be obtained when using %llx and/or %llu ?
Below is a very simple console program that demonstrates the different behavior of printf and wsprintf.
#include "stdafx.h"
#include <Windows.h>
#include <inttypes.h>
int main()
{
DWORD64 OffsetHWM = 0x7123456789012345;
WCHAR BufferBytes[256] = { 0 }; // initialized - no junk in there
// the wprintf below works as expected
wprintf(L"from wprintf : %8llX\n", OffsetHWM);
// this call to wsprintf isn't filling the buffer with the expected value
wsprintf(BufferBytes, L"%8llX\n", OffsetHWM);
wprintf(L"from wsprintf: %s\n", BufferBytes); // prints junk
wprintf(L"\n"); // just for neatness
wsprintf(BufferBytes, L"%8" PRIx64 "\n", OffsetHWM);
wprintf(L"from wsprintf: %s\n", BufferBytes);
// this truncates (as expected) the value of OffsetHWM - not useful
wsprintf(BufferBytes, L"%8lx\n", OffsetHWM);
wprintf(L"from wsprintf: %s\n", BufferBytes);
return 0;
}
wprintf() should not be used any more, it is a Windows specific function which calls either wsprintfA() or wsprintfW() to do the actual work, both of which have the following note on their Windows Dev Centre Documentation site (https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-wsprintfa):
Note Do not use. Consider using one of the following functions instead: StringCbPrintf, StringCbPrintfEx, StringCchPrintf, or StringCchPrintfEx. See Security Considerations.

Viewing call stack for all threads when debugging a multithreaded Windows CE application

So, working with Visual Studio 2008 developing native C++ code for a Windows CE 6.0 platform. Consider the following multithreaded application:
#include "stdafx.h"
void IncrementCounter(int& counter)
{
if (++counter >= 1000)
{
counter = 0;
}
}
unsigned long ThreadFunction(void* arguments)
{
int threadCounter = 0;
while (true)
{
Sleep(20);
IncrementCounter(threadCounter);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunction,
NULL,
0,
NULL
);
int mainCounter = 0;
while (true)
{
Sleep(20);
IncrementCounter(mainCounter);
}
return 0;
}
When I build this to run on my Windows 7 dev. machine and run a debug session from Visual Studio with a breakpoint on the counter = 0; statement, execution will eventually break and two threads will be displayed in the "Threads" debug window. I can switch back and forth between the two threads using either a double-click or right-click->"Switch to Thread" and see a call stack and browse source and inspect symbols (for the call stack frames within my application code) for both threads. However when I do the same on Windows CE connecting via. ActiveSync/WMDC (have tried on both our custom CE 6.0 hardware with an in-house OS and SDK, and an old Windows mobile 5.0 PDA with the stock MS SDK) I can see a call stack and browse source for the thread in which the break has taken place (where the current execution point is within my application code), however I don't get anything useful for the other thread, which is currently blocked in kernel space waiting it's sleep timeout.
Anyone know whether it's possible to get this working better on Windows CE? I'm guessing it might be something to do with the debugger not knowing where to find .pdb symbol files for the WinCE kernel elements, or perhaps do I need to be running a Debug OS?
Windows CE 6 remote debugging. No call stack when pause program describes the same issue, but doesn't really provide a solution
thanks
Richard
Probably its because of missing pdb file for coredll.dll. If you are creating image for your device you will have access to this file, otherwise I am afraid its platform dependent.
You can find here that this issue is considered to be by design in VS2005 so maybe its the same for VS2008:
http://connect.microsoft.com/VisualStudio/feedback/details/190785/unable-to-debug-windows-mobile-application-that-is-in-a-system-call
In following link you can find some instructions for finding call stack using platform builder for "Thread That Is Not Running"
https://distrinet.cs.kuleuven.be/projects/SEESCOA/internal/workpackages/workpackage6/Task6dot2/ESCE/classes/331.pdf
Since I'am using only VS 2005 I cannot confirm if its of any help.
If logging is not sufficient (as was suggested in the SO link you provided), to find call stack for a thread like in your example I suggest using GetThreadCallStack function. Here is a step by step procedure:
1 - Add following code to your project:
typedef struct _CallSnapshotEx {
DWORD dwReturnAddr;
DWORD dwFramePtr;
DWORD dwCurProc;
DWORD dwParams[4];
} CallSnapshotEx;
#define STACKSNAP_EXTENDED_INFO 2
DWORD dwGUIThread;
void DumpGUIThreadCallStack() {
HINSTANCE hCore = LoadLibrary(_T("coredll.dll"));
typedef ULONG (*GETTHREADCALLSTACK)(HANDLE hThrd, ULONG dwMaxFrames, LPVOID lpFrames[], DWORD dwFlags,DWORD dwSkip);
GETTHREADCALLSTACK pGetThreadCallStack = (GETTHREADCALLSTACK)GetProcAddress(hCore, _T("GetThreadCallStack"));
if ( !pGetThreadCallStack )
return;
#define MAX_FRAMES 40
CallSnapshotEx lpFrames[MAX_FRAMES];
DWORD dwCnt = pGetThreadCallStack((HANDLE)dwGUIThread, MAX_FRAMES, (void**)lpFrames, STACKSNAP_EXTENDED_INFO, 0);
TCHAR szBuff[64];
for ( DWORD i = 0; i < dwCnt; ++i ) {
wsprintf(szBuff, L"[%d] %p\n", i, lpFrames[i].dwReturnAddr);
OutputDebugString(szBuff);
}
}
it will dump in Output window call frames return addresses (sample output is in point 3).
2 - initialize dwGUIThread in WinMain:
dwGUIThread = GetCurrentThreadId();
3 - execute DumpGUIThreadCallStack(); before actuall breakpoint inside ThreadFunction. It will write to output window text similar to this:
[0] 8C04D2C4
[1] 8C04D34C
[2] 40026D48
[3] 000111F4 <--- 1
[4] 00011BAC <--- 2
[5] 4003C2DC
1 and 2 are return addresses that you are interested in, and you want to find symbols nearest to them.
4 - while inside debugger switch to disassembly mode (right click on source file and choose 'Go to disassembly'). In this mode at the top of the window you will see Address: line. You should copy paste to it addresses from output window, in my case 000111F4 will direct me to following lines:
while (true)
{
Sleep(20);
000111F0 mov r0, #0x14
000111F4 bl 0001193C // <--- 1
IncrementCounter(mainCounter);
which gives you what your GUI thread is actually doing.
Visual Studio Debugger allows to execute functions from immediate window, but I was unable to call DumpGUIThreadCallStack, I am always getting 'Error: function evaluation not supported'.
To find nearest symbols for frame return addresses you can also use .map files together with .cod files (/FAcs compiled sources), there are some good tutorials on that on google.
Above example was tested with the use of VS 2005 and Standard SDK 5.0, on WCE6.0 (end user) device.

How to include several source files in Nsight Eclipse?

I have a project with many source files (examples: main.cu, a.cu, b.cu, c.cu, d.cu). Each with functions and kernel calls (global and device).
In a header (cpu.h) all the structures and definitions to be used in the host side.
Another header (gpu.h) all the structures and definitions to be used in the device side.
If I call kernel functions from main.cu, declared in a.cu. How do I #include those kernel functions declared in a.cu to use in main.cu, without doing the not recommended #include "a.cu"?
Do I create a header a.h with forward declaration of the kernel function in a.cu? Example:
extern void functionA(type);
What about the CUDA kernel functions? Should I create a header file for each source file that is used from another source file?
Where can I find some simple CUDA examples with multiple source files?
I mention Nsight Eclipse because I am having lots of trouble with it and multiple sources.
I am using CUDA 5.5 Toolkits in a Ubuntu Linux and Mac OS environments.
My main development environment is with 4 Tesla C1060 cards in the Ubuntu Linux machine.
Separating kernels. In a project, create two files (I refactored the default Runtime Project template and created device.cu and host.cu)
device.cu:
__device__ unsigned int bitreverse(unsigned int number) {
number = ((0xf0f0f0f0 & number) >> 4) | ((0x0f0f0f0f & number) << 4);
number = ((0xcccccccc & number) >> 2) | ((0x33333333 & number) << 2);
number = ((0xaaaaaaaa & number) >> 1) | ((0x55555555 & number) << 1);
return number;
}
__global__ void bitreverse(void *data) {
unsigned int *idata = (unsigned int*) data;
idata[threadIdx.x] = bitreverse(idata[threadIdx.x]);
}
host.cu:
extern __global__ void bitreverse(void *data);
...
bitreverse<<<1, WORK_SIZE, WORK_SIZE * sizeof(int)>>>(d);
Separate Compilation
Right-click project, go to properties.
Build/Settings.
Setup build for SM 2.0 or newer.
Select "Separate compilation" radio.
device.cu:
__device__ unsigned int bitreverse(unsigned int number) {
number = ((0xf0f0f0f0 & number) >> 4) | ((0x0f0f0f0f & number) << 4);
number = ((0xcccccccc & number) >> 2) | ((0x33333333 & number) << 2);
number = ((0xaaaaaaaa & number) >> 1) | ((0x55555555 & number) << 1);
return number;
}
host.cu:
extern __device__ unsigned int bitreverse(unsigned int number);
__global__ void bitreverse(void *data) {
unsigned int *idata = (unsigned int*) data;
idata[threadIdx.x] = bitreverse(idata[threadIdx.x]);
}
...
bitreverse<<<1, WORK_SIZE, WORK_SIZE * sizeof(int)>>>(d);
Isolate CUDA code One common pattern is to have CUDA code isolated in .cu files that have a host function wrapping kernel invocation. This way you can link object file produced from such .cu file to host code written in .cpp or .c files. Keep in mind that exported host code function should be qualified with extern "C" to be usable from .c files.
extern declarations can be put in .h file. Note that .h file with CUDA C syntax (__global__ is CUDA C-specific) cannot be included in .cpp or .c.
Adding files to projects
Usually I just copy files to project folder, right-click the project and do "Refresh". Nsight will index them and include in the build.
Excluding files from the build
If you absolutely need to, you can copy device code to headers and include the headers (convention is to have .cuh extension for such header files, though .h works just the same). You can include .cu - the problem is that Nsight considers such files a source files and tries to compile them. You may exclude .cu file from the build by checking "Exclude resource from the build" checkbox in the top of any property page in the Build subtree in build properties.
CUDA multi-file samples
Pretty much any non-trivial sample is broken up into multiple files. Just create an Nsight project from, e.g., "Particles" sample.

can a program read its own elf section?

I would like to use ld's --build-id option in order to add build information to my binary. However, I'm not sure how to make this information available inside the program. Assume I want to write a program that writes a backtrace every time an exception occurs, and a script that parses this information. The script reads the symbol table of the program and searches for the addresses printed in the backtrace (I'm forced to use such a script because the program is statically linked and backtrace_symbols is not working). In order for the script to work correctly I need to match build version of the program with the build version of the program which created the backtrace. How can I print the build version of the program (located in the .note.gnu.build-id elf section) from the program itself?
How can I print the build version of the program (located in the .note.gnu.build-id elf section) from the program itself?
You need to read the ElfW(Ehdr) (at the beginning of the file) to find program headers in your binary (.e_phoff and .e_phnum will tell you where program headers are, and how many of them to read).
You then read program headers, until you find PT_NOTE segment of your program. That segment will tell you offset to the beginning of all the notes in your binary.
You then need to read the ElfW(Nhdr) and skip the rest of the note (total size of the note is sizeof(Nhdr) + .n_namesz + .n_descsz, properly aligned), until you find a note with .n_type == NT_GNU_BUILD_ID.
Once you find NT_GNU_BUILD_ID note, skip past its .n_namesz, and read the .n_descsz bytes to read the actual build-id.
You can verify that you are reading the right data by comparing what you read with the output of readelf -n a.out.
P.S.
If you are going to go through the trouble to decode build-id as above, and if your executable is not stripped, it may be better for you to just decode and print symbol names instead (i.e. to replicate what backtrace_symbols does) -- it's actually easier to do than decoding ELF notes, because the symbol table contains fixed-sized entries.
Basically, this is the code I've written based on answer given to my question. In order to compile the code I had to make some changes and I hope it will work for as many types of platforms as possible. However, it was tested only on one build machine. One of the assumptions I used was that the program was built on the machine which runs it so no point in checking endianness compatibility between the program and the machine.
user#:~/$ uname -s -r -m -o
Linux 3.2.0-45-generic x86_64 GNU/Linux
user#:~/$ g++ test.cpp -o test
user#:~/$ readelf -n test | grep Build
Build ID: dc5c4682e0282e2bd8bc2d3b61cfe35826aa34fc
user#:~/$ ./test
Build ID: dc5c4682e0282e2bd8bc2d3b61cfe35826aa34fc
#include <elf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#if __x86_64__
# define ElfW(type) Elf64_##type
#else
# define ElfW(type) Elf32_##type
#endif
/*
detecting build id of a program from its note section
http://stackoverflow.com/questions/17637745/can-a-program-read-its-own-elf-section
http://www.scs.stanford.edu/histar/src/pkg/uclibc/utils/readelf.c
http://www.sco.com/developers/gabi/2000-07-17/ch5.pheader.html#note_section
*/
int main (int argc, char* argv[])
{
char *thefilename = argv[0];
FILE *thefile;
struct stat statbuf;
ElfW(Ehdr) *ehdr = 0;
ElfW(Phdr) *phdr = 0;
ElfW(Nhdr) *nhdr = 0;
if (!(thefile = fopen(thefilename, "r"))) {
perror(thefilename);
exit(EXIT_FAILURE);
}
if (fstat(fileno(thefile), &statbuf) < 0) {
perror(thefilename);
exit(EXIT_FAILURE);
}
ehdr = (ElfW(Ehdr) *)mmap(0, statbuf.st_size,
PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0);
phdr = (ElfW(Phdr) *)(ehdr->e_phoff + (size_t)ehdr);
while (phdr->p_type != PT_NOTE)
{
++phdr;
}
nhdr = (ElfW(Nhdr) *)(phdr->p_offset + (size_t)ehdr);
while (nhdr->n_type != NT_GNU_BUILD_ID)
{
nhdr = (ElfW(Nhdr) *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz + nhdr->n_descsz);
}
unsigned char * build_id = (unsigned char *)malloc(nhdr->n_descsz);
memcpy(build_id, (void *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz), nhdr->n_descsz);
printf(" Build ID: ");
for (int i = 0 ; i < nhdr->n_descsz ; ++i)
{
printf("%02x",build_id[i]);
}
free(build_id);
printf("\n");
return 0;
}
Yes, a program can read its own .note.gnu.build-id. The important piece is the dl_iterate_phdr function.
I've used this technique in Mesa (the OpenGL/Vulkan implementation) to read its own build-id for use with the on-disk shader cache.
I've extracted those bits into a separate project[1] for easy use by others.
[1] https://github.com/mattst88/build-id

Resources