A little C code "challenge" which puzzled me today.
Why was the following change a no-op?
As background. For DB_LINK, the type stored in
'plink->value.pv_link.pvt' changed from 'DBADDR*'
to 'dbChannel*' back with Base 3.15.0.1. I was
quite surprised to notice that dblsr() was still
treating it as a 'DBADDR*'.I initially assumed
that no one had tested it since then. But, after
thinking for awhile, I realized that the
situation was not so simple.
--- a/modules/database/src/ioc/db/dbLock.c
+++ b/modules/database/src/ioc/db/dbLock.c
@@ -918,7 +918,7 @@ long dblsr(char *recordname,int level)
pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->link_ind[link]];
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
if(plink->type != DB_LINK) continue;
- pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
+ pdbAddr = &((dbChannel *)(plink->value.pv_link.pvt))->addr;
https://urldefense.us/v3/__https://github.com/epics-base/epics-base/commit/72d50ce2749bbc791907a32c1ed77af1333a21f5__;!!G_uCfscf7eWS!bqiRBiT_Ip0nrcLGxrmm1ZE6yiy1TzCcEIkBjZ30UI_daWaDnRhBenpKVMd1dyXCfbUXcYySljDXqZ16jZH7AIP8Qg$
... my answer below ...
My key to understanding was noticing that the only usage
of 'pdbAddr' is to print the record name:
printf(" %s\n",pdbAddr->precord->name);
Now the most obvious answer would be if the struct dbAddr
embedded in the struct dbChannel were the first member.
However, this is not the case.
typedef struct dbChannel {
const char *name; /**< Channel name */
dbAddr addr; /**< Pointers to record & field */
...
The first member of dbAddr is the record pointer:
typedef struct dbAddr {
struct dbCommon *precord; /* address of record */
So
pdbAddr->precord->name
was actually accessing dbChannel::name with the correct
number of indirections (1) because 'precord->name' is not
actually an indirection since the first member is a 'char[]'.
typedef struct dbCommon {
char name[61]; /**< @brief Record Name */
...
So, I wasn't entirely truthful in calling this a no-op.
If a DB_LINK were targeted at a record alias name, then
between 3.15.0.1 and now, dblsr() would print the alias
instead of the intended canonical record name.
Now for the weekend!
- Replies:
- Re: dblsr code question/challenge Zimoch Dirk via Core-talk
- Re: dblsr code question/challenge Kasemir, Kay via Core-talk
- Navigate by Date:
- Prev:
Build failed: epics-base base-link-ext-1042 AppVeyor via Core-talk
- Next:
Build failed: epics-base base-improve_mingw_host_arch_check_msg-60 AppVeyor via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
<2024>
- Navigate by Thread:
- Prev:
Build failed: epics-base base-link-ext-1042 AppVeyor via Core-talk
- Next:
Re: dblsr code question/challenge Zimoch Dirk via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
<2024>
|