具有 DSNAME 长度的 IBM Window Services (DWS) CSRIDAC 无效

Posted

技术标签:

【中文标题】具有 DSNAME 长度的 IBM Window Services (DWS) CSRIDAC 无效【英文标题】:IBM Window Services (DWS) CSRIDAC with DSNAME length not valid 【发布时间】:2018-06-11 07:49:46 【问题描述】:

我正在研究 z/OS 并尝试使用 IBM 提供的窗口服务。 除了通过其 DSNAME 创建一个对象之外,一切都运行良好。

当我使用 DSNAME 调用 CSRIDAC 时出现错误: “系统无法分配或取消分配 数据集指定为 object_name。值 rrrr 是返回码 从动态分配。值 nnnn 是两个字节的原因 来自动态分配的代码。请参阅 z/OS MVS 编程: 动态分配返回的授权组装服务指南 和原因代码。”

于是我搜索了原因码037c的含义,发现:“Invalid LEN specified in text unit.随附的消息IKJ56231I表示错误的文本单元编号。”

因此,窗口服务似乎正在调用动态分配服务以通过其 DSNAME 创建对象,并且在计算我提供的 DSNAME 中的字符数时出错。

我的 DSNAME 是一个有效的 VSAM 文件名,我通过其他方式使用相同的 DSNAME 成功读取了此数据集。

嗯,这是我的函数调用 CSRIDAC 函数的代码:

ozwinsrvObject *ozwinsrvObjectCreate(uint32_t uiFlags, int32_t iObjectSize, uint8_t *pcObjectName, int32_t *piHighOffset, int32_t *piRc)

ozwinsrvObject *pobject = __malloc31(sizeof(ozwinsrvObject));

    *piRc = OZWINSRV_NO_ERROR;
    pobject->pheap = __malloc31(18*4);
    pobject->pparmList = __malloc31(11 * sizeof(int32_t));
    memcpy(&pobject->parmObject.acOpType[0] , "BEGIN", 5);
    pobject->parmObject.iObjectSize = iObjectSize;
    pobject->parmObject.iHighOffset = *piHighOffset;
    if(uiFlags & OZWINSRV_OBJECT_F_TYPE_DDNAME)
    
        memcpy(&pobject->parmObject.acObjectType[0], "DDNAME   ", 9);
    
    else 
        if(uiFlags & OZWINSRV_OBJECT_F_TYPE_DSNAME)
        
            memcpy(&pobject->parmObject.acObjectType[0], "DSNAME   ", 9);
        
        else
        
            memcpy(&pobject->parmObject.acObjectType[0], "TEMPSPACE", 9);
        
    
    if(uiFlags & OZWINSRV_OBJECT_F_SCROLL_AREA_YES)
    
        memcpy(&pobject->parmObject.acScrollArea[0], "YES", 3);
    
    else
    
        memcpy(&pobject->parmObject.acScrollArea[0], "NO ", 3);
    
    if(uiFlags & OZWINSRV_OBJECT_F_STATE_NEW)
    
        memcpy(&pobject->parmObject.acObjectState[0], "NEW", 3);
    
    else
    
        memcpy(&pobject->parmObject.acObjectState[0], "OLD", 3);
    
    if(uiFlags & OZWINSRV_OBJECT_F_ACCESS_MODE_UPDATE)
    
        memcpy(&pobject->parmObject.acAccessMode[0], "UPDATE", 6);
    
    else
    
        memcpy(&pobject->parmObject.acAccessMode[0], "READ  ", 6);
    
    memcpy(&pobject->acObjectName[0], pcObjectName, strlen(pcObjectName));
    if(strlen(pcObjectName) < 45)
    
        pobject->acObjectName[strlen(pcObjectName)] = ' ';
    
    memset(pobject->pparmList, 0, 11 * sizeof(int32_t));
    pobject->pparmList[0] = (int32_t) &pobject->parmObject.acOpType[0];
    pobject->pparmList[1] = (int32_t) &pobject->parmObject.acObjectType[0];
    pobject->pparmList[2] = (int32_t) &pobject->parmObject.acObjectName[0];
    pobject->pparmList[3] = (int32_t) &pobject->parmObject.acScrollArea[0];
    pobject->pparmList[4] = (int32_t) &pobject->parmObject.acObjectState[0];
    pobject->pparmList[5] = (int32_t) &pobject->parmObject.acAccessMode[0];
    pobject->pparmList[6] = (int32_t) &pobject->parmObject.iObjectSize;
    pobject->pparmList[7] = (int32_t) &pobject->acObjectId[0];
    pobject->pparmList[8] = (int32_t) &pobject->parmObject.iHighOffset;
    pobject->pparmList[9] = (int32_t) &pobject->parmObject.iRc;
    pobject->pparmList[10] = (int32_t) &pobject->parmObject.iReasonC;
    x6csridac(pobject->pparmList, pobject->pheap);
    if(pobject->parmObject.iRc != 0)
    
        printf("Error creating object (csridac) Rc=0x%x, ReasonC=0x%x\n", pobject->parmObject.iRc, pobject->parmObject.iReasonC);
        *piRc = OZWINSRV_ERROR_WINDOW_OBJECT_CREATE;
    
    *piHighOffset = pobject->parmObject.iHighOffset;
    pobject->iObjectSize = iObjectSize;
    pobject->uiFlags = uiFlags;
    pobject->uiNbViews = 0;
    return pobject;

那么,这里是调用这个函数的代码:

int32_t iRc = 0;
int32_t iPageSize = 32*1024;
int32_t iPageOffset = iPageSize/4/1024;
int32_t iSize = 1;
int32_t iRealSize = 1;
ozwinsrvObject *pObject;
ozwinsrvWindow *pWindow;
uint8_t acFileName[] = "DSNB10.DSNDBC.DBTLS00.TS1449.I0001.A001";

pObject = ozwinsrvObjectCreate(OZWINSRV_OBJECT_F_ACCESS_MODE_READ | OZWINSRV_OBJECT_F_SCROLL_AREA_NO | OZWINSRV_OBJECT_F_STATE_OLD | OZWINSRV_OBJECT_F_TYPE_DSNAME,
                               iSize, &acFileName[0], &iRealSize, &iRc);

我希望我对问题的解释很清楚。如果不是,请随时提出一些问题。 谢谢!

【问题讨论】:

我不会将此作为答案发布,因为这只是一个猜测,我无法对其进行测试。来自未初始化堆区域的数据集名称中可能有尾随垃圾。 CSRIDAC 文档说“将 object_name 定义为长度为 1 到 44 的字符数据。如果 object_name 包含的字符少于 44 个,请用空格填充右侧的名称。”。您的 if 语句仅将 NUL 设置为空格,因此可能会有尾随垃圾。我会在 acObjectName memcpy 之前添加一个memset(&amp;pobject-&gt;acObjectName[0], ' ', sizeof(acObjectName));(假设 sizeof(acObjectName) 为 44,否则硬编码为 44)。 这会在您移动之前将整个区域初始化为空格,因此当您仅移动输入参数的strlen 时,NUL 之后的区域仍然是空格。然后你可以将 NUL 设置为空格,现在你有一个有效的 44 字节区域和一个数据集名称。要记住的一件事是,这些接口中有许多是在 C 语言之前设计的,因此您必须考虑整个字段的最大长度必须如何(尤其是 DD 名称和 DSN 之类的内容。如果这能解决您的问题,请告诉我们,我会写下来作为答案。 我尝试了您的解决方案,但它并没有解决我的问题。我不确定问题最终出自 DSNAME... Window Services 可以将多个文本单元发送到 Dynamic Allocation 服务。问题是我不知道哪个文本单元抛出错误。有没有办法对此进行一些日志或详细说明? 一种方法是对动态分配错误进行系统转储(如果您不知道如何操作,请阅读 IBM 语言环境调试指南中的 DYNDUMP 和 SYSMDUMP)。获得转储后,找到跟踪表并在转储之前找到 SVC 99 跟踪条目 - 这是动态分配。在 SVC 入口处的 R1 将具有 dynalloc 参数列表(希望也将在您的转储中),从那里,您可能会找出问题所在。 好吧,该死的。不过,我仍然会保留它,以确保您有 44 字节的合法数据作为数据集名称。接下来遵循 Valerie 的建议(转储)。我们可以帮助您解释 SVC 99 文本单元(这很有趣,如果您是自虐狂)。 【参考方案1】:

我发现了我的错误并发布了答案。 我使用以下行将名称复制到数组中:

memcpy(&pobject->acObjectName[0], pcObjectName, strlen(pcObjectName));

但是!当我将此数组放入参数列表时,我使用这行代码:

pobject->pparmList[2] = (int32_t) &pobject->parmObject.acObjectName[0];

这意味着名称在pobject->acObjectName中,我把pobject->parmObject.acObjectName放在参数列表中。这两个数组不是同一个变量...

我很抱歉我的错误并确认 DWS 运行良好。

【讨论】:

以上是关于具有 DSNAME 长度的 IBM Window Services (DWS) CSRIDAC 无效的主要内容,如果未能解决你的问题,请参考以下文章

查询以选择具有特定最后一列的所有表 Ibm Db2 z/os

无法在 IBM MobileFirst 6.3 中调用 window.plugins

IBM Worklight 6.0 - BlackBerry 10 中的 window.open() 失败

IBM Worklight:iOS 推送通知长度限制

过滤具有最小窗口长度的连续序列的 pandas 或 numpy 数组

IBM X3650 M3 安装Windows 2008?