Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions nvme-print-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -2121,11 +2121,11 @@ static void json_boot_part_log(void *bp_log, const char *devname,

/* Printable Eye string is allocated and returned, caller must free */
static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane,
struct json_object *r)
struct json_object *r)
{
char *eye = (char *)lane->eye_desc;
uint16_t nrows = lane->nrows;
uint16_t ncols = lane->ncols;
uint16_t nrows = le16_to_cpu(lane->nrows);
uint16_t ncols = le16_to_cpu(lane->ncols);

if (nrows == 0 || ncols == 0)
return NULL;
Expand All @@ -2139,11 +2139,19 @@ static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane,

struct json_object *eye_array = json_create_array();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are checking for null pointers, then this one should also be checked I suppose.

And don't we need to free it eventually? In this case use the cleanup helpers so that you can exit the funtion at anytime. Can't remember what json-c does, if it takes the owner ship.

Copy link
Contributor Author

@sivaprasad6541 sivaprasad6541 May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! I initially tried using cleanup helpers, but encountered a segfault in the caller while printing the root JSON object. Since the caller is responsible for freeing the memory, I've kept the manual cleanup logic in place to avoid ownership issues.
Added a null check for eye_array now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again declaration go to the beginning of the block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this to beginning of the block.


if (!eye_array) {
free(printable);
return NULL;
}

for (int i = 0; i < nrows; i++) {
char *row = malloc(ncols + 1);

if (!row)
continue;
if (!row) {
// Cleanup on failure
free(printable_start);
return NULL;
}

for (int j = 0; j < ncols; j++) {
char ch = eye[i * ncols + j];
Expand All @@ -2160,7 +2168,7 @@ static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane,

*printable = '\0';

obj_add_array(r, "printable_eye_rows", eye_array);
obj_add_array(r, "printable_eye", eye_array);

return printable_start;
}
Expand Down Expand Up @@ -2197,26 +2205,25 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log,

if (desc->edlen == 0)
continue;
else {
/* Hex dump Vendor Specific Eye Data*/
vsdata = (unsigned char *)malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
char *hexstr = malloc(desc->edlen * 3 + 1); // 2 hex chars + space per byte

if (!hexstr)
return;
/* Hex dump Vendor Specific Eye Data*/
vsdataoffset = (le16_to_cpu(desc->nrows) * le16_to_cpu(desc->ncols)) +
sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would first do the allocation (hexstr) before the computation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.

// 2 hex chars + space per byte
_cleanup_free_ char *hexstr = malloc(le16_to_cpu(desc->edlen) * 3 + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please introduce local variable for nrows ncols and edlen so you only need to to the cpu conversion once.

Also while at it please use consistent comment style.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.


char *p = hexstr;
if (!hexstr)
return;

for (int offset = 0; offset < desc->edlen; offset++)
p += sprintf(p, "%02X ", vsdata[offset]);
*(p - 1) = '\0'; // remove trailing space
char *hexdata = hexstr;

for (int offset = 0; offset < le16_to_cpu(desc->edlen); offset++)
hexdata += sprintf(hexdata, "%02X ", vsdata[offset]);
*(hexdata - 1) = '\0'; // remove trailing space

obj_add_str(jdesc, "vsdata_hex", hexstr);

obj_add_str(jdesc, "vsdata_hex", hexstr);
free(hexstr);
}
array_add_obj(descs, jdesc);

p += log->dsize;
Expand Down
19 changes: 9 additions & 10 deletions nvme-print-stdout.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,16 +811,15 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log)
/* Eye Data field is vendor specific */
if (desc->edlen == 0)
continue;
else {
/* Hex dump Vendor Specific Eye Data */
vsdata = (unsigned char *)malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
printf("Eye Data:\n");
d(vsdata, desc->edlen, 16, 1);
printf("\n");
}

/* Hex dump Vendor Specific Eye Data */
vsdata = malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
printf("Eye Data:\n");
d(vsdata, desc->edlen, 16, 1);
printf("\n");

p += log->dsize;
}
Expand Down