Spent many hours so far trying to get a handle on how to debug a hodgepodge of third-, fourth-, and fifth-party C code.
Doesn't help that I can't seem to get useful trace information; the information can be generated, sure enough, but there doesn't seem to be a capability available, in this configuration, for having the debugger log trace events and proceed, so basically I see a hard-coded breakpoint for each event: not helpful, especially when the problem is timing-sensitive.
Some of this n-th party code uses some approximation of Hungarian notation for variable and type names. Annoying. And...!
I just discovered that some of the actual type names are less than useful. There's a struct pointer being passed, which refers to a global variable, whose type is something long and semi-descriptive; that's typedef'ed to another such type name, and all this eventually resolves to...
...wait for it...
Yup. All the newfangled type checking in modern C, neatly bypassed. But the names are ever so informative to a human reading the code... as long as it's the same human who wrote it, assuming he remembers what conventions he used.
And, of course, the debugger sees it as void *, and won't display the fields in the pointed-to structure.
Anyway, there's some timing-sensitive issue apparently involving uninitialized variables, and I still haven't determined whether it's really related to my attempt to migrate the code to a slightly different build environment, or some horrible bug that's been lurking all along and just hadn't surfaced until now, or something else entirely.
Yeah, there's a better way of handling pointers to various related structures, without making them all void *. In AGROS, there's (for example) a data structure associated with each I/O device. The first, minimal, part of this has a constant format for all device types, defined as struct iodev_data, so pointers are passed around as struct iodev_data *, and typecast to the device-specific type within the driver if necessary.